From 8060d157daf782f103ce3e698bb0d54bff8a3e10 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Wed, 20 Mar 2024 18:15:00 +0100 Subject: [PATCH 01/24] wip storeEncryptedCommitment --- contracts/PreConfirmations.sol | 168 +++++++++++++++------ contracts/interfaces/IPreConfirmations.sol | 15 +- package.json | 1 + test/PreConfirmationConfTest.sol | 102 ++++++++----- 4 files changed, 203 insertions(+), 83 deletions(-) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 2b655c4..e2ed56b 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -25,7 +25,9 @@ contract PreConfCommitmentStore is Ownable { /// @dev EIP-712 Type Hash for preconfirmation bid bytes32 public constant EIP712_BID_TYPEHASH = - keccak256("PreConfBid(string txnHash,uint64 bid,uint64 blockNumber,uint64 decayStartTimeStamp,uint64 decayEndTimeStamp)"); + keccak256( + "PreConfBid(string txnHash,uint64 bid,uint64 blockNumber,uint64 decayStartTimeStamp,uint64 decayEndTimeStamp)" + ); /// @dev commitment counter uint256 public commitmentCount; @@ -51,9 +53,11 @@ contract PreConfCommitmentStore is Ownable { /// @dev Mapping from provider to commitments count mapping(address => uint256) public commitmentsCount; - /// @dev Mapping from address to commitmentss list + /// @dev Mapping from address to commitments list mapping(address => bytes32[]) public providerCommitments; + mapping(address => bytes32[]) public providerEncryptedCommitments; + /// @dev Mapping for blocknumber to list of hash of commitments mapping(uint256 => bytes32[]) public blockCommitments; @@ -61,6 +65,8 @@ contract PreConfCommitmentStore is Ownable { /// @dev Only stores valid commitments mapping(bytes32 => PreConfCommitment) public commitments; + mapping(bytes32 => EncrPreConfCommitment) public encryptedCommitments; + /// @dev Struct for all the information around preconfirmations commitment struct PreConfCommitment { bool commitmentUsed; @@ -78,6 +84,14 @@ contract PreConfCommitmentStore is Ownable { uint256 blockCommitedAt; } + struct EncrPreConfCommitment { + bool commitmentUsed; + address commiter; + bytes32 commitmentDigest; + bytes commitmentSignature; + uint256 blockCommitedAt; + } + /// @dev Event to log successful verifications event SignatureVerified( address indexed signer, @@ -118,7 +132,7 @@ contract PreConfCommitmentStore is Ownable { constructor( address _providerRegistry, address _bidderRegistry, - address _oracle, + address _oracle, address _owner ) { oracle = _oracle; @@ -211,7 +225,6 @@ contract PreConfCommitmentStore is Ownable { ); } - /** * @dev Internal function to verify a bid * @param bid bid id. @@ -234,7 +247,13 @@ contract PreConfCommitmentStore is Ownable { view returns (bytes32 messageDigest, address recoveredAddress, uint256 stake) { - messageDigest = getBidHash(txnHash, bid, blockNumber, decayStartTimeStamp, decayEndTimeStamp); + messageDigest = getBidHash( + txnHash, + bid, + blockNumber, + decayStartTimeStamp, + decayEndTimeStamp + ); recoveredAddress = messageDigest.recover(bidSignature); stake = bidderRegistry.getAllowance(recoveredAddress); require(stake > (10 * bid), "Invalid bid"); @@ -260,11 +279,7 @@ contract PreConfCommitmentStore is Ownable { bytes32 bidHash, bytes memory bidSignature, bytes memory commitmentSignature - ) - public - view - returns (bytes32 preConfHash, address commiterAddress) - { + ) public view returns (bytes32 preConfHash, address commiterAddress) { preConfHash = getPreConfHash( txnHash, bid, @@ -280,13 +295,26 @@ contract PreConfCommitmentStore is Ownable { function getCommitmentIndex( PreConfCommitment memory commitment - ) public pure returns (bytes32){ - return keccak256( - abi.encodePacked( - commitment.commitmentHash, - commitment.commitmentSignature - ) - ); + ) public pure returns (bytes32) { + return + keccak256( + abi.encodePacked( + commitment.commitmentHash, + commitment.commitmentSignature + ) + ); + } + + function getEncryptedCommitmentIndex( + EncrPreConfCommitment memory commitment + ) public pure returns (bytes32) { + return + keccak256( + abi.encodePacked( + commitment.commitmentDigest, + commitment.commitmentSignature + ) + ); } /** @@ -327,12 +355,17 @@ contract PreConfCommitmentStore is Ownable { _bytesToHexString(bidSignature) ); - address commiterAddress = commitmentDigest.recover(commitmentSignature); + address commiterAddress = commitmentDigest.recover( + commitmentSignature + ); require(stake > (10 * bid), "Stake too low"); - require(decayStartTimeStamp < decayEndTimeStamp, "Invalid decay time"); - - PreConfCommitment memory newCommitment = PreConfCommitment( + require( + decayStartTimeStamp < decayEndTimeStamp, + "Invalid decay time" + ); + + PreConfCommitment memory newCommitment = PreConfCommitment( false, bidderAddress, commiterAddress, @@ -356,42 +389,68 @@ contract PreConfCommitmentStore is Ownable { // Push pointers to other mappings providerCommitments[commiterAddress].push(commitmentIndex); blockCommitments[blockNumber].push(commitmentIndex); - + commitmentCount++; commitmentsCount[commiterAddress] += 1; // Check if Bid has bid-amt stored bidderRegistry.LockBidFunds(commitmentDigest, bid, bidderAddress); + } + + return commitmentIndex; + } + + function storeEncryptedCommitment( + bytes32 commitmentDigest, + bytes memory commitmentSignature + ) public returns (bytes32 commitmentIndex) { + { + address commiterAddress = commitmentDigest.recover( + commitmentSignature + ); + EncrPreConfCommitment memory newCommitment = EncrPreConfCommitment( + false, + commiterAddress, + commitmentDigest, + commitmentSignature, + block.number + ); + + commitmentIndex = getEncryptedCommitmentIndex(newCommitment); + + // Store commitment + encryptedCommitments[commitmentIndex] = newCommitment; + + // Push pointers to other mappings + providerEncryptedCommitments[commiterAddress].push(commitmentIndex); + + commitmentCount++; + commitmentsCount[commiterAddress] += 1; } return commitmentIndex; } - /** + /** * @dev Retrieves the list of commitments for a given committer. * @param commiter The address of the committer. * @return A list of PreConfCommitment structures for the specified committer. */ - function getCommitmentsByCommitter(address commiter) - public - view - returns (bytes32[] memory) - { + function getCommitmentsByCommitter( + address commiter + ) public view returns (bytes32[] memory) { return providerCommitments[commiter]; } - - /** + /** * @dev Retrieves the list of commitments for a given block number. - * @param blockNumber The block number. - * @return A list of indexes referencing preconfimration structures for the specified block number. - */ - function getCommitmentsByBlockNumber(uint256 blockNumber) - public - view - returns (bytes32[] memory) - { + * @param blockNumber The block number. + * @return A list of indexes referencing preconfimration structures for the specified block number. + */ + function getCommitmentsByBlockNumber( + uint256 blockNumber + ) public view returns (bytes32[] memory) { return blockCommitments[blockNumber]; } @@ -400,8 +459,9 @@ contract PreConfCommitmentStore is Ownable { * @param commitmentIndex The index of the commitment. * @return txnHash The transaction hash. */ - function getTxnHashFromCommitment(bytes32 commitmentIndex) public view returns (string memory txnHash) - { + function getTxnHashFromCommitment( + bytes32 commitmentIndex + ) public view returns (string memory txnHash) { return commitments[commitmentIndex].txnHash; } @@ -416,11 +476,20 @@ contract PreConfCommitmentStore is Ownable { return commitments[commitmentIndex]; } + function getEncryptedCommitment( + bytes32 commitmentIndex + ) public view returns (EncrPreConfCommitment memory) { + return encryptedCommitments[commitmentIndex]; + } + /** * @dev Initiate a slash for a commitment. * @param commitmentIndex The hash of the commitment to be slashed. */ - function initiateSlash(bytes32 commitmentIndex, uint256 residualBidPercentAfterDecay) public onlyOracle { + function initiateSlash( + bytes32 commitmentIndex, + uint256 residualBidPercentAfterDecay + ) public onlyOracle { PreConfCommitment memory commitment = commitments[commitmentIndex]; require( !commitments[commitmentIndex].commitmentUsed, @@ -442,18 +511,21 @@ contract PreConfCommitmentStore is Ownable { } /** - * @dev Initiate a return of funds for a bid that was not slashed. - * @param commitmentDigest The hash of the bid to be unlocked. + * @dev Initiate a return of funds for a bid that was not slashed. + * @param commitmentDigest The hash of the bid to be unlocked. */ - function unlockBidFunds(bytes32 commitmentDigest) public onlyOracle { + function unlockBidFunds(bytes32 commitmentDigest) public onlyOracle { bidderRegistry.unlockFunds(commitmentDigest); - } + } /** * @dev Initiate a reward for a commitment. * @param commitmentIndex The hash of the commitment to be rewarded. */ - function initiateReward(bytes32 commitmentIndex, uint256 residualBidPercentAfterDecay) public onlyOracle { + function initiateReward( + bytes32 commitmentIndex, + uint256 residualBidPercentAfterDecay + ) public onlyOracle { PreConfCommitment memory commitment = commitments[commitmentIndex]; require( !commitments[commitmentIndex].commitmentUsed, @@ -493,7 +565,9 @@ contract PreConfCommitmentStore is Ownable { * @dev Updates the address of the bidder registry. * @param newBidderRegistry The new bidder registry address. */ - function updateBidderRegistry(address newBidderRegistry) external onlyOwner { + function updateBidderRegistry( + address newBidderRegistry + ) external onlyOwner { bidderRegistry = IBidderRegistry(newBidderRegistry); } diff --git a/contracts/interfaces/IPreConfirmations.sol b/contracts/interfaces/IPreConfirmations.sol index ec5448e..178f6da 100644 --- a/contracts/interfaces/IPreConfirmations.sol +++ b/contracts/interfaces/IPreConfirmations.sol @@ -25,7 +25,13 @@ interface IPreConfCommitmentStore { uint256 blockCommitedAt; } - + struct EncrPreConfCommitment { + bool commitmentUsed; + address commiter; + bytes32 commitmentDigest; + bytes commitmentSignature; + uint256 blockCommitedAt; + } event SignatureVerified( address indexed signer, @@ -70,11 +76,18 @@ interface IPreConfCommitmentStore { bytes memory commitmentSignature ) external returns (uint256); + function storeEncryptedCommitment( + bytes32 commitmentDigest, + bytes memory commitmentSignature + ) external returns (uint256); + function getCommitmentsByBlockNumber(uint256 blockNumber) external view returns (bytes32[] memory); function getCommitment(bytes32 commitmentIndex) external view returns (PreConfCommitment memory); + function getEncryptedCommitment(bytes32 commitmentIndex) external view returns (EncrPreConfCommitment memory); + function initiateSlash(bytes32 commitmentIndex, uint256 residualDecayedBid) external; function initiateReward(bytes32 commitmentIndex, uint256 residualDecayedBid) external; diff --git a/package.json b/package.json index ad52614..901df3a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "typechain": "^8.2.0" }, "dependencies": { + "@openzeppelin/contracts": "^5.0.2", "solc": "^0.8.20", "solidity-docgen": "^0.6.0-beta.36" } diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index 34ffc8e..829a7b2 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -79,47 +79,79 @@ contract TestPreConfCommitmentStore is Test { ); } - function test_CreateCommitment() public { - bytes32 bidHash = preConfCommitmentStore.getBidHash( - _testCommitmentAliceBob.txnHash, - _testCommitmentAliceBob.bid, - _testCommitmentAliceBob.blockNumber, - _testCommitmentAliceBob.decayStartTimestamp, - _testCommitmentAliceBob.decayEndTimestamp - ); - (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); - // Wallet memory kartik = vm.createWallet('test wallet'); - (uint8 v,bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); - bytes memory signature = abi.encodePacked(r, s, v); - - vm.deal(bidder, 200000 ether); - vm.prank(bidder); - bidderRegistry.prepay{value: 1e18 wei}(); - - (bytes32 digest, address recoveredAddress, uint256 stake) = preConfCommitmentStore.verifyBid( - _testCommitmentAliceBob.bid, - _testCommitmentAliceBob.blockNumber, - _testCommitmentAliceBob.decayStartTimestamp, - _testCommitmentAliceBob.decayEndTimestamp, - _testCommitmentAliceBob.txnHash, - signature); + // function test_CreateCommitment() public { + // bytes32 bidHash = preConfCommitmentStore.getBidHash( + // _testCommitmentAliceBob.txnHash, + // _testCommitmentAliceBob.bid, + // _testCommitmentAliceBob.blockNumber, + // _testCommitmentAliceBob.decayStartTimestamp, + // _testCommitmentAliceBob.decayEndTimestamp + // ); + // (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); + // // Wallet memory kartik = vm.createWallet('test wallet'); + // (uint8 v,bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); + // bytes memory signature = abi.encodePacked(r, s, v); + + // vm.deal(bidder, 200000 ether); + // vm.prank(bidder); + // bidderRegistry.prepay{value: 1e18 wei}(); + + // (bytes32 digest, address recoveredAddress, uint256 stake) = preConfCommitmentStore.verifyBid( + // _testCommitmentAliceBob.bid, + // _testCommitmentAliceBob.blockNumber, + // _testCommitmentAliceBob.decayStartTimestamp, + // _testCommitmentAliceBob.decayEndTimestamp, + // _testCommitmentAliceBob.txnHash, + // signature); - assertEq(stake, 1e18 wei); - assertEq(bidder, recoveredAddress); - assertEq(digest, bidHash); + // assertEq(stake, 1e18 wei); + // assertEq(bidder, recoveredAddress); + // assertEq(digest, bidHash); + + // preConfCommitmentStore.storeCommitment( + // _testCommitmentAliceBob.bid, + // _testCommitmentAliceBob.blockNumber, + // _testCommitmentAliceBob.txnHash, + // _testCommitmentAliceBob.decayStartTimestamp, + // _testCommitmentAliceBob.decayEndTimestamp, + // signature, + // _testCommitmentAliceBob.commitmentSignature + // ); + // } + + function test_storeEncryptedCommitment() public { + // Step 1: Prepare the commitment information and signature + bytes32 commitmentDigest = keccak256(abi.encodePacked("commitment data")); + (address committer, uint256 committerPk) = makeAddrAndKey("committer"); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(committerPk, commitmentDigest); + bytes memory commitmentSignature = abi.encodePacked(r, s, v); + + // Optional: Ensure the committer has enough ETH if needed for the operation + vm.deal(committer, 1 ether); + vm.prank(committer); - preConfCommitmentStore.storeCommitment( - _testCommitmentAliceBob.bid, - _testCommitmentAliceBob.blockNumber, - _testCommitmentAliceBob.txnHash, - _testCommitmentAliceBob.decayStartTimestamp, - _testCommitmentAliceBob.decayEndTimestamp, - signature, - _testCommitmentAliceBob.commitmentSignature + // Step 2: Store the commitment + bytes32 commitmentIndex = preConfCommitmentStore.storeEncryptedCommitment( + commitmentDigest, + commitmentSignature ); + // Step 3: Verify the results + // a. Check that the commitment index is correctly generated and not zero + assert(commitmentIndex != bytes32(0)); + + // b. Retrieve the commitment by index and verify its properties + (PreConfCommitmentStore.EncrPreConfCommitment memory commitment) = + preConfCommitmentStore.getEncryptedCommitment(commitmentIndex); + + // c. Assertions to verify the stored commitment matches the input + assertEq(commitment.commitmentUsed, false); + assertEq(commitment.commiter, committer); + assertEq(commitment.commitmentDigest, commitmentDigest); + assertEq(commitment.commitmentSignature, commitmentSignature); } + function test_UpdateOracle() public { preConfCommitmentStore.updateOracle(feeRecipient); assertEq(preConfCommitmentStore.oracle(), feeRecipient); From fa1b502ad3013c6c455564ca69f4d7f2648b75d2 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Wed, 27 Mar 2024 11:52:50 +0100 Subject: [PATCH 02/24] update to support double spend --- contracts/BidderRegistry.sol | 98 +++++++++----- contracts/BlockTracker.sol | 63 +++++++++ contracts/Oracle.sol | 89 +++++++------ contracts/PreConfirmations.sol | 146 +++++++++++++-------- contracts/interfaces/IBidderRegistry.sol | 7 +- contracts/interfaces/IBlockTracker.sol | 31 +++++ contracts/interfaces/IOracle.sol | 5 + contracts/interfaces/IPreConfirmations.sol | 8 +- 8 files changed, 310 insertions(+), 137 deletions(-) create mode 100644 contracts/BlockTracker.sol create mode 100644 contracts/interfaces/IBlockTracker.sol create mode 100644 contracts/interfaces/IOracle.sol diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index db2dfd9..797e7d9 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.15; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IBidderRegistry} from "./interfaces/IBidderRegistry.sol"; +import {IBlockTracker} from "./interfaces/IBlockTracker.sol"; /// @title Bidder Registry /// @author Kartik Chopra @@ -28,6 +29,8 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /// @dev Address of the pre-confirmations contract address public preConfirmationsContract; + IBlockTracker public blockTrackerContract; + /// @dev Fee recipient address public feeRecipient; @@ -35,7 +38,10 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { mapping(address => bool) public bidderRegistered; /// @dev Mapping from bidder addresses to their prepayed amount - mapping(address => uint256) public bidderPrepaidBalances; + // mapping(address => uint256) public bidderPrepaidBalances; + + // Mapping from bidder addresses and window numbers to their locked funds + mapping(address => mapping(uint256 => uint256)) public lockedFunds; /// @dev Mapping from bidder addresses to their locked amount based on bidID (commitmentDigest) mapping(bytes32 => BidState) public BidPayment; @@ -44,11 +50,15 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { mapping(address => uint256) public providerAmount; /// @dev Event emitted when a bidder is registered with their prepayed amount - event BidderRegistered(address indexed bidder, uint256 prepaidAmount); + // event BidderRegistered(address indexed bidder, uint256 prepaidAmount); + event BidderRegistered(address indexed bidder, uint256 prepaidAmount, uint256 windowNumber); /// @dev Event emitted when funds are retrieved from a bidder's prepay event FundsRetrieved(bytes32 indexed commitmentDigest, uint256 amount); + /// @dev Event emitted when a bidder withdraws their prepay + event BidderWithdrawal(address indexed bidder, uint256 window, uint256 amount); + /** * @dev Fallback function to revert all calls, ensuring no unintended interactions. */ @@ -75,11 +85,13 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { uint256 _minAllowance, address _feeRecipient, uint16 _feePercent, - address _owner + address _owner, + address _blockTracker ) { minAllowance = _minAllowance; feeRecipient = _feeRecipient; feePercent = _feePercent; + blockTrackerContract = IBlockTracker(_blockTracker); _transferOwnership(_owner); } @@ -128,10 +140,15 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { function prepay() public payable { require(msg.value >= minAllowance, "Insufficient prepay"); - bidderPrepaidBalances[msg.sender] += msg.value; bidderRegistered[msg.sender] = true; - emit BidderRegistered(msg.sender, bidderPrepaidBalances[msg.sender]); + uint256 currentWindow = blockTrackerContract.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; + + // Lock the funds for the next window + lockedFunds[msg.sender][nextWindow] += msg.value; + + emit BidderRegistered(msg.sender, msg.value, nextWindow); } /** @@ -139,20 +156,9 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * @param bidder The address of the bidder. * @return The prepayed amount for the bidder. */ - function getAllowance(address bidder) external view returns (uint256) { - return bidderPrepaidBalances[bidder]; - } - - function LockBidFunds(bytes32 commitmentDigest, uint64 bid, address bidder) external onlyPreConfirmationEngine(){ - BidState memory bidState = BidPayment[commitmentDigest]; - if (bidState.state == State.Undefined) { - BidPayment[commitmentDigest] = BidState({ - bidAmt: bid, - state: State.PreConfirmed, - bidder: bidder - }); - bidderPrepaidBalances[bidder] -= bid; - } + function getAllowance(address bidder, uint256 window) external view returns (uint256) { + // return bidderPrepaidBalances[bidder]; + return lockedFunds[bidder][window]; } /** @@ -162,6 +168,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * @param provider The address to transfer the retrieved funds to. */ function retrieveFunds( + uint256 windowToSettle, bytes32 commitmentDigest, address payable provider, uint256 residualBidPercentAfterDecay @@ -183,7 +190,8 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { providerAmount[provider] += amtMinusFeeAndDecay; // Ensures the bidder gets back the bid amount - decayed reward given to provider and protocol - bidderPrepaidBalances[bidState.bidder] += bidState.bidAmt - decayedAmt; + lockedFunds[bidState.bidder][windowToSettle] += bidState.bidAmt - decayedAmt; + // bidderPrepaidBalances[bidState.bidder] += bidState.bidAmt - decayedAmt; BidPayment[commitmentDigest].state = State.Withdrawn; BidPayment[commitmentDigest].bidAmt = 0; @@ -196,18 +204,18 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * @dev reenterancy not necessary but still putting here for precaution * @param bidID is the Bid ID that allows us to identify the bid, and prepayment */ - function unlockFunds(bytes32 bidID) external nonReentrant onlyPreConfirmationEngine() { - BidState memory bidState = BidPayment[bidID]; - require(bidState.state == State.PreConfirmed, "The bid was not preconfirmed"); - uint256 amt = bidState.bidAmt; - bidderPrepaidBalances[bidState.bidder] += amt; + // function unlockFunds(bytes32 bidID) external nonReentrant onlyPreConfirmationEngine() { + // BidState memory bidState = BidPayment[bidID]; + // require(bidState.state == State.PreConfirmed, "The bid was not preconfirmed"); + // uint256 amt = bidState.bidAmt; + // bidderPrepaidBalances[bidState.bidder] += amt; - BidPayment[bidID].state = State.Withdrawn; - BidPayment[bidID].bidAmt = 0; + // BidPayment[bidID].state = State.Withdrawn; + // BidPayment[bidID].bidAmt = 0; - emit FundsRetrieved(bidID, amt); - } + // emit FundsRetrieved(bidID, amt); + // } /** * @notice Sets the new fee recipient @@ -246,14 +254,32 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { require(success, "couldn't transfer to provider"); } - function withdrawPrepaidAmount(address payable bidder) external nonReentrant { - uint256 prepaidAmount = bidderPrepaidBalances[bidder]; - bidderPrepaidBalances[bidder] = 0; - require(msg.sender == bidder, "only bidder can unprepay"); - require(prepaidAmount > 0, "bidder prepaid Amount is zero"); + // function withdrawPrepaidAmount(address payable bidder) external nonReentrant { + // uint256 prepaidAmount = bidderPrepaidBalances[bidder]; + // bidderPrepaidBalances[bidder] = 0; + // require(msg.sender == bidder, "only bidder can unprepay"); + // require(prepaidAmount > 0, "bidder prepaid Amount is zero"); - (bool success, ) = bidder.call{value: prepaidAmount}(""); - require(success, "couldn't transfer prepay to bidder"); + // (bool success, ) = bidder.call{value: prepaidAmount}(""); + // require(success, "couldn't transfer prepay to bidder"); + // } + + function withdrawBidderAmountFromWindow( + address payable bidder, + uint256 window + ) external nonReentrant { + require(msg.sender == bidder, "only bidder can withdraw funds from window"); + uint256 currentWindow = blockTrackerContract.getCurrentWindow(); + // withdraw is enabled only is closed and settled + require(window + 1 < currentWindow, "funds can only be withdrawn after the window is settled"); + uint256 amount = lockedFunds[bidder][window]; + lockedFunds[bidder][window] = 0; + require(amount > 0, "bidder Amount is zero"); + + (bool success, ) = bidder.call{value: amount}(""); + require(success, "couldn't transfer to bidder"); + + emit BidderWithdrawal(bidder, window, amount); } function withdrawProtocolFee( diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol new file mode 100644 index 0000000..b3a5512 --- /dev/null +++ b/contracts/BlockTracker.sol @@ -0,0 +1,63 @@ +pragma solidity ^0.8.20; + +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +contract BlockTracker is Ownable { + event NewL1Block(uint256 indexed blockNumber, address indexed winner); + + event NewWindow(uint256 indexed window); + + uint256 public currentWindow; + uint256 public blocksPerWindow = 64; + uint256 public lastL1BlockNumber; + address public lastL1BlockWinner; + + constructor( + address _owner + ) Ownable() { + _transferOwnership(_owner); + } + + function getLastL1BlockNumber() external view returns (uint256) { + return lastL1BlockNumber; + } + + function getLastL1BlockWinner() external view returns (address) { + return lastL1BlockWinner; + } + + function getCurrentWindow() external view returns (uint256) { + return currentWindow; + } + + function recordL1Block( + uint256 _blockNumber, + address _winner + ) external onlyOwner { + lastL1BlockNumber = _blockNumber; + lastL1BlockWinner = _winner; + emit NewL1Block(_blockNumber, _winner); + uint256 newWindow = (_blockNumber - 1) / blocksPerWindow + 1; + if (newWindow > currentWindow) { + // We've entered a new window + currentWindow = newWindow; + + emit NewWindow(currentWindow); + } + } + + /** + * @dev Fallback function to revert all calls, ensuring no unintended interactions. + */ + fallback() external payable { + revert("Invalid call"); + } + + /** + * @dev Receive function is disabled for this contract to prevent unintended interactions. + * Should be removed from here in case the registerAndStake function becomes more complex + */ + receive() external payable { + revert("Invalid call"); + } +} \ No newline at end of file diff --git a/contracts/Oracle.sol b/contracts/Oracle.sol index 7559e14..a19b9ba 100644 --- a/contracts/Oracle.sol +++ b/contracts/Oracle.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.20; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {PreConfCommitmentStore} from "./PreConfirmations.sol"; import {IProviderRegistry} from "./interfaces/IProviderRegistry.sol"; -import {IPreConfCommitmentStore} from './interfaces/IPreConfirmations.sol'; -import {IBidderRegistry} from './interfaces/IBidderRegistry.sol'; - +import {IPreConfCommitmentStore} from "./interfaces/IPreConfirmations.sol"; +import {IBidderRegistry} from "./interfaces/IBidderRegistry.sol"; +import {IBlockTracker} from "./interfaces/IBlockTracker.sol"; /// @title Oracle Contract /// @author Kartik Chopra @@ -20,15 +20,7 @@ contract Oracle is Ownable { /// @dev Maps builder names to their respective Ethereum addresses. mapping(string => address) public blockBuilderNameToAddress; - /// @dev Stores the block number that is next in line to be requested. - uint256 public nextRequestedBlockNumber; - /** - * @dev Returns the next block number that is set to be requested. - */ - function getNextRequestedBlockNumber() external view returns (uint256) { - return nextRequestedBlockNumber; - } // To shutup the compiler /// @dev Empty receive function to silence compiler warnings about missing payable functions. @@ -46,20 +38,22 @@ contract Oracle is Ownable { /// @dev Reference to the PreConfCommitmentStore contract interface. IPreConfCommitmentStore private preConfContract; + IBlockTracker private blockTrackerContract; /** * @dev Constructor to initialize the contract with a PreConfirmations contract. * @param _preConfContract The address of the pre-confirmations contract. - * @param _nextRequestedBlockNumber The next block number to be requested. * @param _owner Owner of the contract, explicitly needed since contract is deployed with create2 factory. */ constructor( address _preConfContract, - uint256 _nextRequestedBlockNumber, + address _blockTrackerContract, + // uint256 _nextRequestedBlockNumber, address _owner ) Ownable() { preConfContract = IPreConfCommitmentStore(_preConfContract); - nextRequestedBlockNumber = _nextRequestedBlockNumber; + // nextRequestedBlockNumber = _nextRequestedBlockNumber; + blockTrackerContract = IBlockTracker(_blockTrackerContract); _transferOwnership(_owner); } @@ -71,7 +65,10 @@ contract Oracle is Ownable { * @param builderName The name of the block builder as it appears on extra data. * @param builderAddress The Ethereum address of the builder. */ - function addBuilderAddress(string memory builderName, address builderAddress) external onlyOwner { + function addBuilderAddress( + string memory builderName, + address builderAddress + ) external onlyOwner { blockBuilderNameToAddress[builderName] = builderAddress; } @@ -79,7 +76,9 @@ contract Oracle is Ownable { * @dev Returns the builder's address corresponding to the given name. * @param builderNameGrafiti The name (or graffiti) of the block builder. */ - function getBuilder(string calldata builderNameGrafiti) external view returns (address) { + function getBuilder( + string calldata builderNameGrafiti + ) external view returns (address) { return blockBuilderNameToAddress[builderNameGrafiti]; } @@ -100,32 +99,27 @@ contract Oracle is Ownable { ) external onlyOwner { // Check graffiti against registered builder IDs address builder = blockBuilderNameToAddress[blockBuilderName]; - require(residualBidPercentAfterDecay <= 100, "Residual bid after decay cannot be greater than 100 percent"); - IPreConfCommitmentStore.PreConfCommitment memory commitment = preConfContract.getCommitment(commitmentIndex); - if (commitment.commiter == builder && commitment.blockNumber == blockNumber) { - processCommitment(commitmentIndex, isSlash, residualBidPercentAfterDecay); + require( + residualBidPercentAfterDecay <= 100, + "Residual bid after decay cannot be greater than 100 percent" + ); + IPreConfCommitmentStore.PreConfCommitment + memory commitment = preConfContract.getCommitment(commitmentIndex); + if ( + commitment.commiter == builder && + commitment.blockNumber == blockNumber + ) { + processCommitment( + commitmentIndex, + isSlash, + residualBidPercentAfterDecay + ); } - } /** - * @dev Sets the next block number to be requested. - * @param newBlockNumber The new block number to be set. - */ - function setNextBlock(uint64 newBlockNumber) external onlyOwner { - nextRequestedBlockNumber = newBlockNumber; - } - - /** - * @dev Increments the `nextRequestedBlockNumber` by one. - */ - function moveToNextBlock() external onlyOwner { - nextRequestedBlockNumber++; - } - - /** - * @dev unlocks funds to the bidders assosciated with BidIDs in the input array. - * @param bidIDs The array of BidIDs to unlock funds for. + * @dev unlocks funds to the bidders assosciated with BidIDs in the input array. + * @param bidIDs The array of BidIDs to unlock funds for. */ function unlockFunds(bytes32[] memory bidIDs) external onlyOwner { for (uint256 i = 0; i < bidIDs.length; i++) { @@ -138,11 +132,24 @@ contract Oracle is Ownable { * @param commitmentIndex The id of the commitment to be processed. * @param isSlash Determines if the commitment should be slashed or rewarded. */ - function processCommitment(bytes32 commitmentIndex, bool isSlash, uint256 residualBidPercentAfterDecay) private { + function processCommitment( + bytes32 commitmentIndex, + bool isSlash, + uint256 residualBidPercentAfterDecay + ) private { if (isSlash) { - preConfContract.initiateSlash(commitmentIndex, residualBidPercentAfterDecay); + preConfContract.initiateSlash( + commitmentIndex, + residualBidPercentAfterDecay + ); } else { - preConfContract.initiateReward(commitmentIndex, residualBidPercentAfterDecay); + // processing commitment after window has been settled + uint256 windowToSettle = blockTrackerContract.getCurrentWindow() - 1; + preConfContract.initiateReward( + windowToSettle, + commitmentIndex, + residualBidPercentAfterDecay + ); } // Emit an event that a commitment has been processed emit CommitmentProcessed(commitmentIndex, isSlash); diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index e2ed56b..3cfbfb2 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -82,8 +82,25 @@ contract PreConfCommitmentStore is Ownable { bytes bidSignature; bytes commitmentSignature; uint256 blockCommitedAt; + bytes sharedSecretKey; } + event CommitmentStored( + address bidder, + address commiter, + uint64 bid, + uint64 blockNumber, + bytes32 bidHash, + uint64 decayStartTimeStamp, + uint64 decayEndTimeStamp, + string txnHash, + bytes32 commitmentHash, + bytes bidSignature, + bytes commitmentSignature, + uint256 blockCommitedAt, + bytes sharedSecretKey + ); + struct EncrPreConfCommitment { bool commitmentUsed; address commiter; @@ -203,7 +220,8 @@ contract PreConfCommitmentStore is Ownable { uint64 _decayStartTimeStamp, uint64 _decayEndTimeStamp, bytes32 _bidHash, - string memory _bidSignature + string memory _bidSignature, + string memory _sharedSecretKey ) public view returns (bytes32) { return ECDSA.toTypedDataHash( @@ -219,7 +237,8 @@ contract PreConfCommitmentStore is Ownable { keccak256( abi.encodePacked(_bytes32ToHexString(_bidHash)) ), - keccak256(abi.encodePacked(_bidSignature)) + keccak256(abi.encodePacked(_bidSignature)), + keccak256(abi.encodePacked(_sharedSecretKey)) ) ) ); @@ -233,7 +252,6 @@ contract PreConfCommitmentStore is Ownable { * @param bidSignature bid signature. * @return messageDigest returns the bid hash for given bid id. * @return recoveredAddress the address from the bid hash. - * @return stake the stake amount of the address for bid id bidder. */ function verifyBid( uint64 bid, @@ -245,7 +263,7 @@ contract PreConfCommitmentStore is Ownable { ) public view - returns (bytes32 messageDigest, address recoveredAddress, uint256 stake) + returns (bytes32 messageDigest, address recoveredAddress) { messageDigest = getBidHash( txnHash, @@ -255,43 +273,41 @@ contract PreConfCommitmentStore is Ownable { decayEndTimeStamp ); recoveredAddress = messageDigest.recover(bidSignature); - stake = bidderRegistry.getAllowance(recoveredAddress); - require(stake > (10 * bid), "Invalid bid"); } - /** - * @dev Verifies a pre-confirmation commitment by computing the hash and recovering the committer's address. - * @param txnHash The transaction hash associated with the commitment. - * @param bid The bid amount. - * @param blockNumber The block number at the time of the bid. - * @param bidHash The hash of the bid details. - * @param bidSignature The signature of the bid. - * @param commitmentSignature The signature of the commitment. - * @return preConfHash The hash of the pre-confirmation commitment. - * @return commiterAddress The address of the committer recovered from the commitment signature. - */ - function verifyPreConfCommitment( - string memory txnHash, - uint64 bid, - uint64 blockNumber, - uint64 decayStartTimeStamp, - uint64 decayEndTimeStamp, - bytes32 bidHash, - bytes memory bidSignature, - bytes memory commitmentSignature - ) public view returns (bytes32 preConfHash, address commiterAddress) { - preConfHash = getPreConfHash( - txnHash, - bid, - blockNumber, - decayStartTimeStamp, - decayEndTimeStamp, - bidHash, - _bytesToHexString(bidSignature) - ); - - commiterAddress = preConfHash.recover(commitmentSignature); - } + // /** + // * @dev Verifies a pre-confirmation commitment by computing the hash and recovering the committer's address. + // * @param txnHash The transaction hash associated with the commitment. + // * @param bid The bid amount. + // * @param blockNumber The block number at the time of the bid. + // * @param bidHash The hash of the bid details. + // * @param bidSignature The signature of the bid. + // * @param commitmentSignature The signature of the commitment. + // * @return preConfHash The hash of the pre-confirmation commitment. + // * @return commiterAddress The address of the committer recovered from the commitment signature. + // */ + // function verifyPreConfCommitment( + // string memory txnHash, + // uint64 bid, + // uint64 blockNumber, + // uint64 decayStartTimeStamp, + // uint64 decayEndTimeStamp, + // bytes32 bidHash, + // bytes memory bidSignature, + // bytes memory commitmentSignature + // ) public view returns (bytes32 preConfHash, address commiterAddress) { + // preConfHash = getPreConfHash( + // txnHash, + // bid, + // blockNumber, + // decayStartTimeStamp, + // decayEndTimeStamp, + // bidHash, + // _bytesToHexString(bidSignature) + // ); + + // commiterAddress = preConfHash.recover(commitmentSignature); + // } function getCommitmentIndex( PreConfCommitment memory commitment @@ -326,16 +342,18 @@ contract PreConfCommitmentStore is Ownable { * @param commitmentSignature The signature of the commitment. * @return commitmentIndex The index of the stored commitment */ - function storeCommitment( + function storeOpenCommitment( + bytes32 encryptedCommitmentIndex, uint64 bid, uint64 blockNumber, string memory txnHash, uint64 decayStartTimeStamp, uint64 decayEndTimeStamp, bytes calldata bidSignature, - bytes memory commitmentSignature + bytes memory commitmentSignature, + bytes memory sharedSecretKey ) public returns (bytes32 commitmentIndex) { - (bytes32 bHash, address bidderAddress, uint256 stake) = verifyBid( + (bytes32 bHash, address bidderAddress) = verifyBid( bid, blockNumber, decayStartTimeStamp, @@ -352,14 +370,21 @@ contract PreConfCommitmentStore is Ownable { decayStartTimeStamp, decayEndTimeStamp, bHash, - _bytesToHexString(bidSignature) + _bytesToHexString(bidSignature), + _bytesToHexString(sharedSecretKey) + ); + EncrPreConfCommitment memory encryptedCommitment = encryptedCommitments[encryptedCommitmentIndex]; + require( + !encryptedCommitment.commitmentUsed, + "Commitment already used" ); + + require(encryptedCommitment.commitmentDigest == commitmentDigest, "Invalid commitment digest"); address commiterAddress = commitmentDigest.recover( commitmentSignature ); - require(stake > (10 * bid), "Stake too low"); require( decayStartTimeStamp < decayEndTimeStamp, "Invalid decay time" @@ -378,7 +403,8 @@ contract PreConfCommitmentStore is Ownable { commitmentDigest, bidSignature, commitmentSignature, - block.number + block.number, + sharedSecretKey ); commitmentIndex = getCommitmentIndex(newCommitment); @@ -390,11 +416,21 @@ contract PreConfCommitmentStore is Ownable { providerCommitments[commiterAddress].push(commitmentIndex); blockCommitments[blockNumber].push(commitmentIndex); - commitmentCount++; - commitmentsCount[commiterAddress] += 1; - - // Check if Bid has bid-amt stored - bidderRegistry.LockBidFunds(commitmentDigest, bid, bidderAddress); + emit CommitmentStored( + bidderAddress, + commiterAddress, + bid, + blockNumber, + bHash, + decayStartTimeStamp, + decayEndTimeStamp, + txnHash, + commitmentDigest, + bidSignature, + commitmentSignature, + block.number, + sharedSecretKey + ); } return commitmentIndex; @@ -507,22 +543,23 @@ contract PreConfCommitmentStore is Ownable { residualBidPercentAfterDecay ); - bidderRegistry.unlockFunds(commitment.commitmentHash); + // bidderRegistry.unlockFunds(commitment.commitmentHash); } /** * @dev Initiate a return of funds for a bid that was not slashed. * @param commitmentDigest The hash of the bid to be unlocked. */ - function unlockBidFunds(bytes32 commitmentDigest) public onlyOracle { - bidderRegistry.unlockFunds(commitmentDigest); - } + // function unlockBidFunds(bytes32 commitmentDigest) public onlyOracle { + // bidderRegistry.unlockFunds(commitmentDigest); + // } /** * @dev Initiate a reward for a commitment. * @param commitmentIndex The hash of the commitment to be rewarded. */ function initiateReward( + uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualBidPercentAfterDecay ) public onlyOracle { @@ -537,6 +574,7 @@ contract PreConfCommitmentStore is Ownable { commitmentsCount[commitment.commiter] -= 1; bidderRegistry.retrieveFunds( + windowToSettle, commitment.commitmentHash, payable(commitment.commiter), residualBidPercentAfterDecay diff --git a/contracts/interfaces/IBidderRegistry.sol b/contracts/interfaces/IBidderRegistry.sol index 0b4e1b9..fd91c61 100644 --- a/contracts/interfaces/IBidderRegistry.sol +++ b/contracts/interfaces/IBidderRegistry.sol @@ -27,15 +27,16 @@ interface IBidderRegistry { function prepay() external payable; - function LockBidFunds(bytes32 commitmentDigest, uint64 bid, address bidder) external; + // function LockBidFunds(bytes32 commitmentDigest, uint64 bid, address bidder) external; - function getAllowance(address bidder) external view returns (uint256); + // function getAllowance(address bidder) external view returns (uint256); function retrieveFunds( + uint256 windowToSettle, bytes32 commitmentDigest, address payable provider, uint256 residualBidPercentAfterDecay ) external; - function unlockFunds(bytes32 bidID) external; + // function unlockFunds(bytes32 bidID) external; } diff --git a/contracts/interfaces/IBlockTracker.sol b/contracts/interfaces/IBlockTracker.sol new file mode 100644 index 0000000..1261b14 --- /dev/null +++ b/contracts/interfaces/IBlockTracker.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +/// @title IBlockTracker interface for BlockTracker contract +interface IBlockTracker { + /// @notice Retrieves the number of the last L1 block tracked. + /// @return The block number of the last tracked L1 block. + function getLastL1BlockNumber() external view returns (uint256); + + /// @notice Retrieves the winner of the last L1 block tracked. + /// @return The address of the winner of the last tracked L1 block. + function getLastL1BlockWinner() external view returns (address); + + /// @notice Retrieves the current window. + /// @return The current window number. + function getCurrentWindow() external view returns (uint256); + + /// @notice Records a new L1 block with its winner. + /// @param _blockNumber The block number of the new L1 block. + /// @param _winner The address of the winner of the new L1 block. + function recordL1Block(uint256 _blockNumber, address _winner) external; + + /// @notice Emitted when a new L1 block is recorded. + /// @param blockNumber The block number of the new L1 block. + /// @param winner The address of the winner of the new L1 block. + event NewL1Block(uint256 indexed blockNumber, address indexed winner); + + /// @notice Emitted when entering a new window. + /// @param window The new window number. + event NewWindow(uint256 indexed window); +} diff --git a/contracts/interfaces/IOracle.sol b/contracts/interfaces/IOracle.sol new file mode 100644 index 0000000..d13a99b --- /dev/null +++ b/contracts/interfaces/IOracle.sol @@ -0,0 +1,5 @@ +pragma solidity ^0.8.20; + +interface IOracle { + function getCurrentWindow() external view returns (uint256); +} diff --git a/contracts/interfaces/IPreConfirmations.sol b/contracts/interfaces/IPreConfirmations.sol index 178f6da..887dc0d 100644 --- a/contracts/interfaces/IPreConfirmations.sol +++ b/contracts/interfaces/IPreConfirmations.sol @@ -67,13 +67,15 @@ interface IPreConfCommitmentStore { bytes calldata bidSignature ) external view returns (bytes32 messageDigest, address recoveredAddress, uint256 stake); - function storeCommitment( + function storeOpenCommitment( + bytes32 encryptedCommitmentIndex, uint64 bid, uint64 blockNumber, string memory txnHash, string memory commitmentHash, bytes calldata bidSignature, - bytes memory commitmentSignature + bytes memory commitmentSignature, + bytes memory sharedSecretKey ) external returns (uint256); function storeEncryptedCommitment( @@ -90,7 +92,7 @@ interface IPreConfCommitmentStore { function initiateSlash(bytes32 commitmentIndex, uint256 residualDecayedBid) external; - function initiateReward(bytes32 commitmentIndex, uint256 residualDecayedBid) external; + function initiateReward(uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualDecayedBid) external; function unlockBidFunds(bytes32 commitmentDigest) external; From 4187e8b388d26cda76460e0fc92e1a1872ba3464 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Wed, 27 Mar 2024 11:56:55 +0100 Subject: [PATCH 03/24] deleted IOracle.sol --- contracts/interfaces/IOracle.sol | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 contracts/interfaces/IOracle.sol diff --git a/contracts/interfaces/IOracle.sol b/contracts/interfaces/IOracle.sol deleted file mode 100644 index d13a99b..0000000 --- a/contracts/interfaces/IOracle.sol +++ /dev/null @@ -1,5 +0,0 @@ -pragma solidity ^0.8.20; - -interface IOracle { - function getCurrentWindow() external view returns (uint256); -} From d7e8f812093dae811f18d5aa4eb7c59c8c016bd1 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Wed, 27 Mar 2024 12:01:36 +0100 Subject: [PATCH 04/24] added bidder getAllowance function --- contracts/interfaces/IBidderRegistry.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/interfaces/IBidderRegistry.sol b/contracts/interfaces/IBidderRegistry.sol index fd91c61..e459710 100644 --- a/contracts/interfaces/IBidderRegistry.sol +++ b/contracts/interfaces/IBidderRegistry.sol @@ -29,7 +29,7 @@ interface IBidderRegistry { // function LockBidFunds(bytes32 commitmentDigest, uint64 bid, address bidder) external; - // function getAllowance(address bidder) external view returns (uint256); + function getAllowance(address bidder, uint256 window) external view returns (uint256); function retrieveFunds( uint256 windowToSettle, From 97848dee4842691eb78e19b0582ca21df866f010 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Thu, 28 Mar 2024 17:30:35 +0100 Subject: [PATCH 05/24] fixed all tests! --- contracts/BidderRegistry.sol | 105 +++++-- contracts/Oracle.sol | 9 +- contracts/PreConfirmations.sol | 81 +++--- contracts/ProviderRegistry.sol | 5 +- contracts/interfaces/IBidderRegistry.sol | 4 +- contracts/interfaces/IPreConfirmations.sol | 6 +- test/BidderRegistryTest.sol | 121 ++++---- test/OracleTest.sol | 83 +++--- test/PreConfirmationConfTest.sol | 306 +++++++++++++++------ test/ProviderRegistryTest.sol | 7 +- 10 files changed, 483 insertions(+), 244 deletions(-) diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index 797e7d9..2f2d88c 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -5,6 +5,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IBidderRegistry} from "./interfaces/IBidderRegistry.sol"; import {IBlockTracker} from "./interfaces/IBlockTracker.sol"; +import "forge-std/console.sol"; /// @title Bidder Registry /// @author Kartik Chopra @@ -51,13 +52,21 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /// @dev Event emitted when a bidder is registered with their prepayed amount // event BidderRegistered(address indexed bidder, uint256 prepaidAmount); - event BidderRegistered(address indexed bidder, uint256 prepaidAmount, uint256 windowNumber); + event BidderRegistered( + address indexed bidder, + uint256 prepaidAmount, + uint256 windowNumber + ); /// @dev Event emitted when funds are retrieved from a bidder's prepay - event FundsRetrieved(bytes32 indexed commitmentDigest, uint256 amount); + event FundsRetrieved(bytes32 indexed commitmentDigest, uint256 window, uint256 amount); /// @dev Event emitted when a bidder withdraws their prepay - event BidderWithdrawal(address indexed bidder, uint256 window, uint256 amount); + event BidderWithdrawal( + address indexed bidder, + uint256 window, + uint256 amount + ); /** * @dev Fallback function to revert all calls, ensuring no unintended interactions. @@ -123,14 +132,16 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /** * @dev Get the amount assigned to a provider. */ - function getProviderAmount(address provider) external view returns (uint256) { + function getProviderAmount( + address provider + ) external view returns (uint256) { return providerAmount[provider]; } - + /** * @dev Get the amount assigned to the fee recipient (treasury). */ - function getFeeRecipientAmount() external onlyOwner view returns (uint256) { + function getFeeRecipientAmount() external view onlyOwner returns (uint256) { return feeRecipientAmount; } @@ -148,7 +159,11 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { // Lock the funds for the next window lockedFunds[msg.sender][nextWindow] += msg.value; - emit BidderRegistered(msg.sender, msg.value, nextWindow); + emit BidderRegistered( + msg.sender, + lockedFunds[msg.sender][nextWindow], + nextWindow + ); } /** @@ -156,7 +171,10 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * @param bidder The address of the bidder. * @return The prepayed amount for the bidder. */ - function getAllowance(address bidder, uint256 window) external view returns (uint256) { + function getAllowance( + address bidder, + uint256 window + ) external view returns (uint256) { // return bidderPrepaidBalances[bidder]; return lockedFunds[bidder][window]; } @@ -173,12 +191,17 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { address payable provider, uint256 residualBidPercentAfterDecay ) external nonReentrant onlyPreConfirmationEngine { - BidState memory bidState = BidPayment[commitmentDigest]; - require(bidState.state == State.PreConfirmed, "The bid was not preconfirmed"); - uint256 decayedAmt = ( bidState.bidAmt * residualBidPercentAfterDecay * PRECISION) / PERCENT; + require( + bidState.state == State.PreConfirmed, + "The bid was not preconfirmed" + ); + uint256 decayedAmt = (bidState.bidAmt * + residualBidPercentAfterDecay * + PRECISION) / PERCENT; - uint256 feeAmt = (decayedAmt * uint256(feePercent) * PRECISION) / PERCENT; + uint256 feeAmt = (decayedAmt * uint256(feePercent) * PRECISION) / + PERCENT; uint256 amtMinusFeeAndDecay = decayedAmt - feeAmt; if (feeRecipient != address(0)) { @@ -190,13 +213,15 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { providerAmount[provider] += amtMinusFeeAndDecay; // Ensures the bidder gets back the bid amount - decayed reward given to provider and protocol - lockedFunds[bidState.bidder][windowToSettle] += bidState.bidAmt - decayedAmt; + lockedFunds[bidState.bidder][windowToSettle] += + bidState.bidAmt - + decayedAmt; // bidderPrepaidBalances[bidState.bidder] += bidState.bidAmt - decayedAmt; BidPayment[commitmentDigest].state = State.Withdrawn; BidPayment[commitmentDigest].bidAmt = 0; - emit FundsRetrieved(commitmentDigest, decayedAmt); + emit FundsRetrieved(commitmentDigest, windowToSettle, decayedAmt); } /** @@ -204,18 +229,40 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * @dev reenterancy not necessary but still putting here for precaution * @param bidID is the Bid ID that allows us to identify the bid, and prepayment */ - // function unlockFunds(bytes32 bidID) external nonReentrant onlyPreConfirmationEngine() { - // BidState memory bidState = BidPayment[bidID]; - // require(bidState.state == State.PreConfirmed, "The bid was not preconfirmed"); - // uint256 amt = bidState.bidAmt; - // bidderPrepaidBalances[bidState.bidder] += amt; + function unlockFunds(uint256 window, bytes32 bidID) external nonReentrant onlyPreConfirmationEngine() { + BidState memory bidState = BidPayment[bidID]; + require(bidState.state == State.PreConfirmed, "The bid was not preconfirmed"); + uint256 amt = bidState.bidAmt; + lockedFunds[bidState.bidder][window] += amt; + BidPayment[bidID].state = State.Withdrawn; + BidPayment[bidID].bidAmt = 0; - // BidPayment[bidID].state = State.Withdrawn; - // BidPayment[bidID].bidAmt = 0; - - // emit FundsRetrieved(bidID, amt); - // } + emit FundsRetrieved(bidID, window, amt); + } + + /** + * @dev Open a bid (only callable by the pre-confirmations contract). + * @param commitmentDigest is the Bid ID that allows us to identify the bid, and prepayment + * @param bid The bid amount. + * @param bidder The address of the bidder. + */ + function OpenBid( + bytes32 commitmentDigest, + uint64 bid, + address bidder + ) external onlyPreConfirmationEngine { + BidState memory bidState = BidPayment[commitmentDigest]; + if (bidState.state == State.Undefined) { + BidPayment[commitmentDigest] = BidState({ + state: State.PreConfirmed, + bidder: bidder, + bidAmt: bid + }); + uint256 currentWindow = blockTrackerContract.getCurrentWindow(); + lockedFunds[bidder][currentWindow] -= bid; + } + } /** * @notice Sets the new fee recipient @@ -268,10 +315,16 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { address payable bidder, uint256 window ) external nonReentrant { - require(msg.sender == bidder, "only bidder can withdraw funds from window"); + require( + msg.sender == bidder, + "only bidder can withdraw funds from window" + ); uint256 currentWindow = blockTrackerContract.getCurrentWindow(); // withdraw is enabled only is closed and settled - require(window + 1 < currentWindow, "funds can only be withdrawn after the window is settled"); + require( + window + 1 < currentWindow, + "funds can only be withdrawn after the window is settled" + ); uint256 amount = lockedFunds[bidder][window]; lockedFunds[bidder][window] = 0; require(amount > 0, "bidder Amount is zero"); diff --git a/contracts/Oracle.sol b/contracts/Oracle.sol index a19b9ba..7ac6def 100644 --- a/contracts/Oracle.sol +++ b/contracts/Oracle.sol @@ -121,9 +121,9 @@ contract Oracle is Ownable { * @dev unlocks funds to the bidders assosciated with BidIDs in the input array. * @param bidIDs The array of BidIDs to unlock funds for. */ - function unlockFunds(bytes32[] memory bidIDs) external onlyOwner { + function unlockFunds(uint256 window, bytes32[] memory bidIDs) external onlyOwner { for (uint256 i = 0; i < bidIDs.length; i++) { - preConfContract.unlockBidFunds(bidIDs[i]); + preConfContract.unlockBidFunds(window, bidIDs[i]); } } @@ -137,14 +137,15 @@ contract Oracle is Ownable { bool isSlash, uint256 residualBidPercentAfterDecay ) private { + // processing commitment after window has been settled + uint256 windowToSettle = blockTrackerContract.getCurrentWindow() - 1; if (isSlash) { preConfContract.initiateSlash( + windowToSettle, commitmentIndex, residualBidPercentAfterDecay ); } else { - // processing commitment after window has been settled - uint256 windowToSettle = blockTrackerContract.getCurrentWindow() - 1; preConfContract.initiateReward( windowToSettle, commitmentIndex, diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 3cfbfb2..20ed8ce 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -275,39 +275,41 @@ contract PreConfCommitmentStore is Ownable { recoveredAddress = messageDigest.recover(bidSignature); } - // /** - // * @dev Verifies a pre-confirmation commitment by computing the hash and recovering the committer's address. - // * @param txnHash The transaction hash associated with the commitment. - // * @param bid The bid amount. - // * @param blockNumber The block number at the time of the bid. - // * @param bidHash The hash of the bid details. - // * @param bidSignature The signature of the bid. - // * @param commitmentSignature The signature of the commitment. - // * @return preConfHash The hash of the pre-confirmation commitment. - // * @return commiterAddress The address of the committer recovered from the commitment signature. - // */ - // function verifyPreConfCommitment( - // string memory txnHash, - // uint64 bid, - // uint64 blockNumber, - // uint64 decayStartTimeStamp, - // uint64 decayEndTimeStamp, - // bytes32 bidHash, - // bytes memory bidSignature, - // bytes memory commitmentSignature - // ) public view returns (bytes32 preConfHash, address commiterAddress) { - // preConfHash = getPreConfHash( - // txnHash, - // bid, - // blockNumber, - // decayStartTimeStamp, - // decayEndTimeStamp, - // bidHash, - // _bytesToHexString(bidSignature) - // ); - - // commiterAddress = preConfHash.recover(commitmentSignature); - // } + /** + * @dev Verifies a pre-confirmation commitment by computing the hash and recovering the committer's address. + * @param txnHash The transaction hash associated with the commitment. + * @param bid The bid amount. + * @param blockNumber The block number at the time of the bid. + * @param bidHash The hash of the bid details. + * @param bidSignature The signature of the bid. + * @param commitmentSignature The signature of the commitment. + * @return preConfHash The hash of the pre-confirmation commitment. + * @return commiterAddress The address of the committer recovered from the commitment signature. + */ + function verifyPreConfCommitment( + string memory txnHash, + uint64 bid, + uint64 blockNumber, + uint64 decayStartTimeStamp, + uint64 decayEndTimeStamp, + bytes32 bidHash, + bytes memory bidSignature, + bytes memory commitmentSignature, + bytes memory sharedSecretKey + ) public view returns (bytes32 preConfHash, address commiterAddress) { + preConfHash = getPreConfHash( + txnHash, + bid, + blockNumber, + decayStartTimeStamp, + decayEndTimeStamp, + bidHash, + _bytesToHexString(bidSignature), + _bytesToHexString(sharedSecretKey) + ); + + commiterAddress = preConfHash.recover(commitmentSignature); + } function getCommitmentIndex( PreConfCommitment memory commitment @@ -342,7 +344,7 @@ contract PreConfCommitmentStore is Ownable { * @param commitmentSignature The signature of the commitment. * @return commitmentIndex The index of the stored commitment */ - function storeOpenCommitment( + function openCommitment( bytes32 encryptedCommitmentIndex, uint64 bid, uint64 blockNumber, @@ -416,6 +418,8 @@ contract PreConfCommitmentStore is Ownable { providerCommitments[commiterAddress].push(commitmentIndex); blockCommitments[blockNumber].push(commitmentIndex); + bidderRegistry.OpenBid(commitmentDigest, bid, bidderAddress); + emit CommitmentStored( bidderAddress, commiterAddress, @@ -523,6 +527,7 @@ contract PreConfCommitmentStore is Ownable { * @param commitmentIndex The hash of the commitment to be slashed. */ function initiateSlash( + uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualBidPercentAfterDecay ) public onlyOracle { @@ -543,16 +548,16 @@ contract PreConfCommitmentStore is Ownable { residualBidPercentAfterDecay ); - // bidderRegistry.unlockFunds(commitment.commitmentHash); + bidderRegistry.unlockFunds(windowToSettle, commitment.commitmentHash); } /** * @dev Initiate a return of funds for a bid that was not slashed. * @param commitmentDigest The hash of the bid to be unlocked. */ - // function unlockBidFunds(bytes32 commitmentDigest) public onlyOracle { - // bidderRegistry.unlockFunds(commitmentDigest); - // } + function unlockBidFunds(uint256 windowToSettle,bytes32 commitmentDigest) public onlyOracle { + bidderRegistry.unlockFunds(windowToSettle, commitmentDigest); + } /** * @dev Initiate a reward for a commitment. diff --git a/contracts/ProviderRegistry.sol b/contracts/ProviderRegistry.sol index 5619795..a3cd84f 100644 --- a/contracts/ProviderRegistry.sol +++ b/contracts/ProviderRegistry.sol @@ -5,6 +5,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {PreConfCommitmentStore} from "./PreConfirmations.sol"; import {IProviderRegistry} from "./interfaces/IProviderRegistry.sol"; +import "forge-std/console.sol"; /// @title Provider Registry /// @author Kartik Chopra @@ -115,7 +116,7 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { function registerAndStake() public payable { require(!providerRegistered[msg.sender], "Provider already registered"); require(msg.value >= minStake, "Insufficient stake"); - + console.log(msg.sender); providerStakes[msg.sender] = msg.value; providerRegistered[msg.sender] = true; @@ -155,6 +156,8 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { uint256 residualBidPercentAfterDecay ) external nonReentrant onlyPreConfirmationEngine { uint256 residualAmt = (amt * residualBidPercentAfterDecay * PRECISION) / PERCENT; + console.log(residualAmt); + console.log(providerStakes[provider]); require(providerStakes[provider] >= residualAmt, "Insufficient funds to slash"); providerStakes[provider] -= residualAmt; diff --git a/contracts/interfaces/IBidderRegistry.sol b/contracts/interfaces/IBidderRegistry.sol index e459710..98aca88 100644 --- a/contracts/interfaces/IBidderRegistry.sol +++ b/contracts/interfaces/IBidderRegistry.sol @@ -29,6 +29,8 @@ interface IBidderRegistry { // function LockBidFunds(bytes32 commitmentDigest, uint64 bid, address bidder) external; + function OpenBid(bytes32 commitmentDigest, uint64 bid, address bidder) external; + function getAllowance(address bidder, uint256 window) external view returns (uint256); function retrieveFunds( @@ -38,5 +40,5 @@ interface IBidderRegistry { uint256 residualBidPercentAfterDecay ) external; - // function unlockFunds(bytes32 bidID) external; + function unlockFunds(uint256 windowToSettle, bytes32 bidID) external; } diff --git a/contracts/interfaces/IPreConfirmations.sol b/contracts/interfaces/IPreConfirmations.sol index 887dc0d..c9e64a8 100644 --- a/contracts/interfaces/IPreConfirmations.sol +++ b/contracts/interfaces/IPreConfirmations.sol @@ -67,7 +67,7 @@ interface IPreConfCommitmentStore { bytes calldata bidSignature ) external view returns (bytes32 messageDigest, address recoveredAddress, uint256 stake); - function storeOpenCommitment( + function openCommitment( bytes32 encryptedCommitmentIndex, uint64 bid, uint64 blockNumber, @@ -90,11 +90,11 @@ interface IPreConfCommitmentStore { function getEncryptedCommitment(bytes32 commitmentIndex) external view returns (EncrPreConfCommitment memory); - function initiateSlash(bytes32 commitmentIndex, uint256 residualDecayedBid) external; + function initiateSlash(uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualDecayedBid) external; function initiateReward(uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualDecayedBid) external; - function unlockBidFunds(bytes32 commitmentDigest) external; + function unlockBidFunds(uint256 windowToSettle, bytes32 commitmentDigest) external; function updateOracle(address newOracle) external; diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index 62b77e3..f39e854 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.20; import "forge-std/Test.sol"; import {BidderRegistry} from "../contracts/BidderRegistry.sol"; +import {BlockTracker} from "../contracts/BlockTracker.sol"; contract BidderRegistryTest is Test { uint256 testNumber; @@ -11,17 +12,18 @@ contract BidderRegistryTest is Test { uint256 internal minStake; address internal bidder; address internal feeRecipient; + BlockTracker internal blockTracker; /// @dev Event emitted when a bidder is registered with their staked amount - event BidderRegistered(address indexed bidder, uint256 stakedAmount); + event BidderRegistered(address indexed bidder, uint256 stakedAmount, uint256 windowNumber); function setUp() public { testNumber = 42; feePercent = 10; minStake = 1e18 wei; feeRecipient = vm.addr(9); - - bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this)); + blockTracker = new BlockTracker(address(this)); + bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this), address(blockTracker)); bidder = vm.addr(1); vm.deal(bidder, 100 ether); @@ -43,26 +45,33 @@ contract BidderRegistryTest is Test { } function test_BidderStakeAndRegister() public { + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; + vm.startPrank(bidder); vm.expectEmit(true, false, false, true); - emit BidderRegistered(bidder, 1 ether); + emit BidderRegistered(bidder, 1 ether, nextWindow); bidderRegistry.prepay{value: 1 ether}(); bool isBidderRegistered = bidderRegistry.bidderRegistered(bidder); assertEq(isBidderRegistered, true); - uint256 bidderStakeStored = bidderRegistry.getAllowance(bidder); + uint256 bidderStakeStored = bidderRegistry.getAllowance(bidder, nextWindow); assertEq(bidderStakeStored, 1 ether); + // For the second prepay, calculate the new next window + currentWindow = blockTracker.getCurrentWindow(); + nextWindow = currentWindow + 1; + vm.expectEmit(true, false, false, true); - emit BidderRegistered(bidder, 2 ether); + emit BidderRegistered(bidder, 2 ether, nextWindow); bidderRegistry.prepay{value: 1 ether}(); - uint256 bidderStakeStored2 = bidderRegistry.getAllowance(bidder); + uint256 bidderStakeStored2 = bidderRegistry.getAllowance(bidder, nextWindow); assertEq(bidderStakeStored2, 2 ether); } @@ -131,18 +140,27 @@ contract BidderRegistryTest is Test { function test_shouldRetrieveFunds() public { bytes32 bidID = keccak256("1234"); bidderRegistry.setPreconfirmationsContract(address(this)); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; + vm.prank(bidder); bidderRegistry.prepay{value: 2 ether}(); address provider = vm.addr(4); - bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); - bidderRegistry.retrieveFunds(bidID, payable(provider),100); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, provider); + + bidderRegistry.OpenBid(bidID, 1 ether, bidder); + + bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); uint256 providerAmount = bidderRegistry.providerAmount(provider); uint256 feeRecipientAmount = bidderRegistry.feeRecipientAmount(); assertEq(providerAmount, 900000000000000000); assertEq(feeRecipientAmount, 100000000000000000); assertEq(bidderRegistry.getFeeRecipientAmount(), 100000000000000000); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 1 ether); + + assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 1 ether); + // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 1 ether); } function test_shouldRetrieveFundsWithoutFeeRecipient() public { @@ -152,12 +170,18 @@ contract BidderRegistryTest is Test { bidderRegistry.setNewFeeRecipient(address(0)); bidderRegistry.setPreconfirmationsContract(address(this)); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; vm.prank(bidder); bidderRegistry.prepay{value: 2 ether}(); + address provider = vm.addr(4); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, provider); bytes32 bidID = keccak256("1234"); - bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); - bidderRegistry.retrieveFunds(bidID, payable(provider),100); + bidderRegistry.OpenBid(bidID, 1 ether, bidder); + // bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); + bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); uint256 feerecipientValueAfter = bidderRegistry.feeRecipientAmount(); uint256 providerAmount = bidderRegistry.providerAmount(provider); @@ -165,17 +189,21 @@ contract BidderRegistryTest is Test { assertEq(providerAmount, 900000000000000000); assertEq(feerecipientValueAfter, feerecipientValueBefore); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 1 ether); + assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 1 ether); + // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 1 ether); } function testFail_shouldRetrieveFundsNotPreConf() public { vm.prank(bidder); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; bidderRegistry.prepay{value: 2 ether}(); address provider = vm.addr(4); vm.expectRevert(bytes("")); bytes32 bidID = keccak256("1234"); - bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); - bidderRegistry.retrieveFunds(bidID, payable(provider),100); + bidderRegistry.OpenBid(bidID, 1 ether, bidder); + // bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); + bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); } function testFail_shouldRetrieveFundsGreaterThanStake() public { @@ -183,25 +211,34 @@ contract BidderRegistryTest is Test { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; bidderRegistry.prepay{value: 2 ether}(); address provider = vm.addr(4); vm.expectRevert(bytes("")); vm.prank(address(this)); bytes32 bidID = keccak256("1234"); - bidderRegistry.LockBidFunds(bidID, 3 ether, bidder); - bidderRegistry.retrieveFunds(bidID, payable(provider),100); + bidderRegistry.OpenBid(bidID, 3 ether, bidder); + // bidderRegistry.LockBidFunds(bidID, 3 ether, bidder); + bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); } function test_withdrawFeeRecipientAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); bidderRegistry.prepay{value: 2 ether}(); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; address provider = vm.addr(4); uint256 balanceBefore = feeRecipient.balance; bytes32 bidID = keccak256("1234"); - bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); - bidderRegistry.retrieveFunds(bidID, payable(provider),100); + // bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, provider); + + bidderRegistry.OpenBid(bidID, 1 ether, bidder); + bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); bidderRegistry.withdrawFeeRecipientAmount(); uint256 balanceAfter = feeRecipient.balance; assertEq(balanceAfter - balanceBefore, 100000000000000000); @@ -218,11 +255,18 @@ contract BidderRegistryTest is Test { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); bidderRegistry.prepay{value: 5 ether}(); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; address provider = vm.addr(4); uint256 balanceBefore = address(provider).balance; bytes32 bidID = keccak256("1234"); - bidderRegistry.LockBidFunds(bidID, 2 ether, bidder); - bidderRegistry.retrieveFunds(bidID, payable(provider), 100); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, provider); + + bidderRegistry.OpenBid(bidID, 2 ether, bidder); + // bidderRegistry.LockBidFunds(bidID, 2 ether, bidder); + + bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); bidderRegistry.withdrawProviderAmount(payable(provider)); uint256 balanceAfter = address(provider).balance; assertEq(balanceAfter - balanceBefore, 1800000000000000000); @@ -237,41 +281,22 @@ contract BidderRegistryTest is Test { bidderRegistry.withdrawProviderAmount(payable(provider)); } - function test_withdrawStakedAmount() public { - bidderRegistry.setPreconfirmationsContract(address(this)); - vm.prank(bidder); - bidderRegistry.prepay{value: 5 ether}(); - uint256 balanceBefore = address(bidder).balance; - vm.prank(bidder); - bidderRegistry.withdrawPrepaidAmount(payable(bidder)); - uint256 balanceAfter = address(bidder).balance; - assertEq(balanceAfter - balanceBefore, 5 ether); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 0); - } - - function testFail_withdrawStakedAmountNotOwner() public { - bidderRegistry.setPreconfirmationsContract(address(this)); - vm.prank(bidder); - bidderRegistry.prepay{value: 5 ether}(); - bidderRegistry.withdrawPrepaidAmount(payable(bidder)); - } - - function testFail_withdrawStakedAmountStakeZero() public { - bidderRegistry.setPreconfirmationsContract(address(this)); - vm.prank(bidder); - bidderRegistry.withdrawPrepaidAmount(payable(bidder)); - } - function test_withdrawProtocolFee() public { address provider = vm.addr(4); bidderRegistry.setPreconfirmationsContract(address(this)); bidderRegistry.setNewFeeRecipient(address(0)); vm.prank(bidder); bidderRegistry.prepay{value: 5 ether}(); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; uint256 balanceBefore = address(bidder).balance; bytes32 bidID = keccak256("1234"); - bidderRegistry.LockBidFunds(bidID, 2 ether, bidder); - bidderRegistry.retrieveFunds(bidID, payable(provider), 100); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, provider); + + // bidderRegistry.LockBidFunds(bidID, 2 ether, bidder); + bidderRegistry.OpenBid(bidID, 2 ether, bidder); + bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); vm.prank(bidderRegistry.owner()); bidderRegistry.withdrawProtocolFee(payable(address(bidder))); uint256 balanceAfter = address(bidder).balance; diff --git a/test/OracleTest.sol b/test/OracleTest.sol index d64b92a..0ec15d4 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -7,6 +7,7 @@ import "../contracts/PreConfirmations.sol"; import "../contracts/interfaces/IPreConfirmations.sol"; import "../contracts/ProviderRegistry.sol"; import "../contracts/BidderRegistry.sol"; +import "../contracts/BlockTracker.sol"; contract OracleTest is Test { address internal owner; @@ -20,7 +21,9 @@ contract OracleTest is Test { uint256 testNumber; uint64 testNumber2; BidderRegistry internal bidderRegistry; + BlockTracker internal blockTracker; TestCommitment internal _testCommitmentAliceBob; + bytes internal sharedSecretKey; struct TestCommitment { uint64 bid; @@ -38,12 +41,12 @@ contract OracleTest is Test { event BlockDataRequested(uint256 blockNumber); event BlockDataReceived(string[] txnList, uint256 blockNumber, string blockBuilderName); event CommitmentProcessed(bytes32 commitmentHash, bool isSlash); - event FundsRetrieved(bytes32 indexed commitmentDigest, uint256 amount); + event FundsRetrieved(bytes32 indexed commitmentDigest, uint256 window, uint256 amount); function setUp() public { testNumber = 2; testNumber2 = 2; - + sharedSecretKey = abi.encodePacked(keccak256("0xsecret")); _testCommitmentAliceBob = TestCommitment( 2, 2, @@ -66,7 +69,9 @@ contract OracleTest is Test { feePercent, address(this) ); - bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this)); + address ownerInstance = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3; + blockTracker = new BlockTracker(ownerInstance); + bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this), address(blockTracker)); preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry address(bidderRegistry), // User Registry @@ -74,12 +79,11 @@ contract OracleTest is Test { address(this) // Owner ); - address ownerInstance = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3; vm.deal(ownerInstance, 5 ether); vm.startPrank(ownerInstance); bidderRegistry.prepay{value: 2 ether}(); - oracle = new Oracle(address(preConfCommitmentStore), 2, ownerInstance); + oracle = new Oracle(address(preConfCommitmentStore), address(blockTracker), ownerInstance); oracle.addBuilderAddress("mev builder", ownerInstance); vm.stopPrank(); @@ -142,7 +146,8 @@ contract OracleTest is Test { _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, bidderPk, - providerPk + providerPk, + provider ); string[] memory txnList = new string[](1); @@ -172,7 +177,7 @@ contract OracleTest is Test { providerRegistry.registerAndStake{value: 250 ether}(); vm.stopPrank(); - bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk); + bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk, provider); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); oracle.addBuilderAddress(blockBuilderName, provider); @@ -202,7 +207,7 @@ contract OracleTest is Test { providerRegistry.registerAndStake{value: 250 ether}(); vm.stopPrank(); - bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk); + bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk, provider); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); oracle.addBuilderAddress(blockBuilderName, provider); @@ -236,8 +241,8 @@ contract OracleTest is Test { providerRegistry.registerAndStake{value: 250 ether}(); vm.stopPrank(); - bytes32 index1 = constructAndStoreCommitment(bid, blockNumber, txn1, 10, 20, bidderPk, providerPk); - bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk); + bytes32 index1 = constructAndStoreCommitment(bid, blockNumber, txn1, 10, 20, bidderPk, providerPk, provider); + bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk, provider); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); oracle.addBuilderAddress(blockBuilderName, provider); @@ -276,10 +281,10 @@ contract OracleTest is Test { providerRegistry.registerAndStake{value: 250 ether}(); vm.stopPrank(); - bytes32 index1 = constructAndStoreCommitment(bid, blockNumber, txn1, 10, 20, bidderPk, providerPk); - bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk); - bytes32 index3 = constructAndStoreCommitment(bid, blockNumber, txn3, 10, 20, bidderPk, providerPk); - bytes32 index4 = constructAndStoreCommitment(bid, blockNumber, txn4, 10, 20, bidderPk, providerPk); + bytes32 index1 = constructAndStoreCommitment(bid, blockNumber, txn1, 10, 20, bidderPk, providerPk, provider); + bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk, provider); + bytes32 index3 = constructAndStoreCommitment(bid, blockNumber, txn3, 10, 20, bidderPk, providerPk, provider); + bytes32 index4 = constructAndStoreCommitment(bid, blockNumber, txn4, 10, 20, bidderPk, providerPk, provider); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); @@ -323,14 +328,14 @@ contract OracleTest is Test { providerRegistry.registerAndStake{value: 250 ether}(); vm.stopPrank(); - bytes32 index1 = constructAndStoreCommitment(bid, blockNumber, txn1, 10, 20, bidderPk, providerPk); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - bid); - bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 2*bid); - bytes32 index3 = constructAndStoreCommitment(bid, blockNumber, txn3, 10, 20, bidderPk, providerPk); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 3*bid); - bytes32 index4 = constructAndStoreCommitment(bid, blockNumber, txn4, 10, 20, bidderPk, providerPk); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 4*bid); + bytes32 index1 = constructAndStoreCommitment(bid, blockNumber, txn1, 10, 20, bidderPk, providerPk, provider); + // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - bid); + bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk, provider); + // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 2*bid); + bytes32 index3 = constructAndStoreCommitment(bid, blockNumber, txn3, 10, 20, bidderPk, providerPk, provider); + // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 3*bid); + bytes32 index4 = constructAndStoreCommitment(bid, blockNumber, txn4, 10, 20, bidderPk, providerPk, provider); + // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 4*bid); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); oracle.addBuilderAddress(blockBuilderName, provider); @@ -370,20 +375,22 @@ contract OracleTest is Test { providerRegistry.registerAndStake{value: 250 ether}(); vm.stopPrank(); - bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk); + bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk, provider); PreConfCommitmentStore.PreConfCommitment memory commitment = preConfCommitmentStore.getCommitment(index); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); bytes32[] memory commitments = new bytes32[](1); commitments[0] = commitment.commitmentHash; - + uint256 window = blockTracker.getCurrentWindow(); vm.expectEmit(true, false, false, true); - emit FundsRetrieved(commitment.commitmentHash, bid); - oracle.unlockFunds(commitments); - + emit FundsRetrieved(commitment.commitmentHash, window, bid); + oracle.unlockFunds(window, commitments); + uint256 currentWindow = blockTracker.getCurrentWindow(); + assertEq(providerRegistry.checkStake(provider) , 250 ether); - assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether); + assertEq(bidderRegistry.lockedFunds(bidder, currentWindow), 250 ether); + // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether); } @@ -397,7 +404,8 @@ contract OracleTest is Test { uint64 decayStartTimestamp, uint64 decayEndTimestamp, uint256 bidderPk, - uint256 signerPk + uint256 signerPk, + address provider ) public returns (bytes32 commitmentIndex) { bytes32 bidHash = preConfCommitmentStore.getBidHash( txnHash, @@ -418,20 +426,31 @@ contract OracleTest is Test { decayStartTimestamp, decayEndTimestamp, bidHash, - _bytesToHexString(bidSignature) + _bytesToHexString(bidSignature), + _bytesToHexString(sharedSecretKey) ); (v,r,s) = vm.sign(signerPk, commitmentHash); bytes memory commitmentSignature = abi.encodePacked(r, s, v); - commitmentIndex = preConfCommitmentStore.storeCommitment( + bytes32 encryptedCommitmentIndex = preConfCommitmentStore.storeEncryptedCommitment( + commitmentHash, + commitmentSignature + ); + uint256 l1BlockNumber = 2; + vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); + blockTracker.recordL1Block(l1BlockNumber, provider); + vm.stopPrank(); + commitmentIndex = preConfCommitmentStore.openCommitment( + encryptedCommitmentIndex, bid, blockNumber, txnHash, decayStartTimestamp, decayEndTimestamp, bidSignature, - commitmentSignature + commitmentSignature, + sharedSecretKey ); return commitmentIndex; diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index 829a7b2..c45ad4a 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -7,7 +7,8 @@ import "forge-std/Test.sol"; import {PreConfCommitmentStore} from "../contracts/PreConfirmations.sol"; import "../contracts/ProviderRegistry.sol"; import "../contracts/BidderRegistry.sol"; - +import "../contracts/BlockTracker.sol"; +import "forge-std/console.sol"; contract TestPreConfCommitmentStore is Test { struct TestCommitment { @@ -20,6 +21,7 @@ contract TestPreConfCommitmentStore is Test { bytes32 commitmentDigest; bytes bidSignature; bytes commitmentSignature; + bytes sharedSecretKey; } TestCommitment internal _testCommitmentAliceBob; @@ -29,6 +31,7 @@ contract TestPreConfCommitmentStore is Test { address internal provider; address internal feeRecipient; ProviderRegistry internal providerRegistry; + BlockTracker internal blockTracker; BidderRegistry internal bidderRegistry; @@ -40,9 +43,10 @@ contract TestPreConfCommitmentStore is Test { 10, 20, 0xa0327970258c49b922969af74d60299a648c50f69a2d98d6ab43f32f64ac2100, - 0x54c118e537dd7cf63b5388a5fc8322f0286a978265d0338b108a8ca9d155dccc, + 0x668206f9c4d620188852ee94940d37c4829b3d99fb702e10cd1804989662980f, hex"876c1216c232828be9fabb14981c8788cebdf6ed66e563c4a2ccc82a577d052543207aeeb158a32d8977736797ae250c63ef69a82cd85b727da21e20d030fb311b", - hex"ec0f11f77a9e96bb9c2345f031a5d12dca8d01de8a2e957cf635be14802f9ad01c6183688f0c2672639e90cc2dce0662d9bea3337306ca7d4b56dd80326aaa231b" + hex"88194da2231873946f5c05b8dc447c430fa7356996617e07d01c4eabebca553044c7e2220c5699f3ad57ff474a1df14ad6f7a8eb9891f57932270f0157c984361b", + abi.encodePacked(keccak256("0xsecret")) ); feePercent = 10; @@ -54,8 +58,8 @@ contract TestPreConfCommitmentStore is Test { feePercent, address(this) ); - - bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this)); + blockTracker = new BlockTracker(address(this)); + bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this), address(blockTracker)); preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry @@ -79,46 +83,6 @@ contract TestPreConfCommitmentStore is Test { ); } - // function test_CreateCommitment() public { - // bytes32 bidHash = preConfCommitmentStore.getBidHash( - // _testCommitmentAliceBob.txnHash, - // _testCommitmentAliceBob.bid, - // _testCommitmentAliceBob.blockNumber, - // _testCommitmentAliceBob.decayStartTimestamp, - // _testCommitmentAliceBob.decayEndTimestamp - // ); - // (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); - // // Wallet memory kartik = vm.createWallet('test wallet'); - // (uint8 v,bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); - // bytes memory signature = abi.encodePacked(r, s, v); - - // vm.deal(bidder, 200000 ether); - // vm.prank(bidder); - // bidderRegistry.prepay{value: 1e18 wei}(); - - // (bytes32 digest, address recoveredAddress, uint256 stake) = preConfCommitmentStore.verifyBid( - // _testCommitmentAliceBob.bid, - // _testCommitmentAliceBob.blockNumber, - // _testCommitmentAliceBob.decayStartTimestamp, - // _testCommitmentAliceBob.decayEndTimestamp, - // _testCommitmentAliceBob.txnHash, - // signature); - - // assertEq(stake, 1e18 wei); - // assertEq(bidder, recoveredAddress); - // assertEq(digest, bidHash); - - // preConfCommitmentStore.storeCommitment( - // _testCommitmentAliceBob.bid, - // _testCommitmentAliceBob.blockNumber, - // _testCommitmentAliceBob.txnHash, - // _testCommitmentAliceBob.decayStartTimestamp, - // _testCommitmentAliceBob.decayEndTimestamp, - // signature, - // _testCommitmentAliceBob.commitmentSignature - // ); - // } - function test_storeEncryptedCommitment() public { // Step 1: Prepare the commitment information and signature bytes32 commitmentDigest = keccak256(abi.encodePacked("commitment data")); @@ -187,7 +151,6 @@ contract TestPreConfCommitmentStore is Test { function test_GetCommitmentDigest() public { (, uint256 bidderPk) = makeAddrAndKey("alice"); - bytes32 bidHash = preConfCommitmentStore.getBidHash( _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.bid, @@ -198,6 +161,7 @@ contract TestPreConfCommitmentStore is Test { (uint8 v,bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); bytes memory signature = abi.encodePacked(r, s, v); + bytes memory sharedSecretKey = abi.encodePacked(keccak256("0xsecret")); bytes32 preConfHash = preConfCommitmentStore.getPreConfHash( _testCommitmentAliceBob.txnHash, @@ -206,12 +170,18 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, bidHash, - _bytesToHexString(signature) + _bytesToHexString(signature), + _bytesToHexString(sharedSecretKey) ); assertEq( preConfHash, _testCommitmentAliceBob.commitmentDigest ); + + (, uint256 providerPk) = makeAddrAndKey("bob"); + ( v, r, s) = vm.sign(providerPk, preConfHash); + signature = abi.encodePacked(r, s, v); + console.logBytes(signature); } @@ -232,7 +202,7 @@ contract TestPreConfCommitmentStore is Test { vm.deal(bidder, 5 ether); vm.prank(bidder); bidderRegistry.prepay{value: 2 ether}(); - + // Step 1: Verify that the commitment has not been used before verifyCommitmentNotUsed( _testCommitmentAliceBob.txnHash, @@ -244,14 +214,31 @@ contract TestPreConfCommitmentStore is Test { ); // Step 2: Store the commitment - bytes32 index = storeCommitment( + bytes32 encryptedIndex = storeCommitment( + _testCommitmentAliceBob.bid, + _testCommitmentAliceBob.blockNumber, + _testCommitmentAliceBob.txnHash, + _testCommitmentAliceBob.decayStartTimestamp, + _testCommitmentAliceBob.decayEndTimestamp, + _testCommitmentAliceBob.bidSignature, + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey + ); + + // Step 4: Move to the next window + blockTracker.recordL1Block(2, address(this)); + + // Step 5: Open the commitment + bytes32 index = openCommitment( + encryptedIndex, _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, _testCommitmentAliceBob.bidSignature, - _testCommitmentAliceBob.commitmentSignature + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey ); // Step 3: Verify the stored commitment @@ -263,10 +250,13 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayEndTimestamp, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.bidSignature, - _testCommitmentAliceBob.commitmentSignature + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey ); string memory commitmentTxnHash = preConfCommitmentStore.getTxnHashFromCommitment(index); + console.log(commitmentTxnHash); + console.log(_testCommitmentAliceBob.txnHash); assertEq(commitmentTxnHash, _testCommitmentAliceBob.txnHash); } @@ -285,6 +275,7 @@ contract TestPreConfCommitmentStore is Test { decayStartTimestamp, decayEndTimestamp ); + bytes memory sharedSecretKey = abi.encodePacked(keccak256("0xsecret")); bytes32 preConfHash = preConfCommitmentStore.getPreConfHash( txnHash, bid, @@ -292,10 +283,11 @@ contract TestPreConfCommitmentStore is Test { decayStartTimestamp, decayEndTimestamp, bidHash, - _bytesToHexString(bidSignature) + _bytesToHexString(bidSignature), + _bytesToHexString(sharedSecretKey) ); - (bool commitmentUsed, , , , , , , , , , , , ) = preConfCommitmentStore + (bool commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(preConfHash); assertEq(commitmentUsed, false); @@ -309,16 +301,73 @@ contract TestPreConfCommitmentStore is Test { uint64 decayStartTimestamp, uint64 decayEndTimestamp, bytes memory bidSignature, - bytes memory commitmentSignature + bytes memory commitmentSignature, + bytes memory sharedSecretKey ) internal returns (bytes32) { - bytes32 commitmentIndex = preConfCommitmentStore.storeCommitment( + bytes32 bidHash = preConfCommitmentStore.getBidHash( + txnHash, + bid, + blockNumber, + decayStartTimestamp, + decayEndTimestamp + ); + + bytes32 commitmentHash = preConfCommitmentStore.getPreConfHash( + txnHash, + bid, + blockNumber, + decayStartTimestamp, + decayEndTimestamp, + bidHash, + _bytesToHexString(bidSignature), + _bytesToHexString(sharedSecretKey) + ); + + bytes32 commitmentIndex = preConfCommitmentStore.storeEncryptedCommitment(commitmentHash, commitmentSignature); + + return commitmentIndex; + } + + function openCommitment( + bytes32 encryptedCommitmentIndex, + uint64 bid, + uint64 blockNumber, + string memory txnHash, + uint64 decayStartTimestamp, + uint64 decayEndTimestamp, + bytes memory bidSignature, + bytes memory commitmentSignature, + bytes memory sharedSecretKey + ) internal returns (bytes32) { + bytes32 bidHash = preConfCommitmentStore.getBidHash( + txnHash, + bid, + blockNumber, + decayStartTimestamp, + decayEndTimestamp + ); + + bytes32 commitmentHash = preConfCommitmentStore.getPreConfHash( + txnHash, + bid, + blockNumber, + decayStartTimestamp, + decayEndTimestamp, + bidHash, + _bytesToHexString(bidSignature), + _bytesToHexString(sharedSecretKey) + ); + + bytes32 commitmentIndex = preConfCommitmentStore.openCommitment( + encryptedCommitmentIndex, bid, blockNumber, txnHash, decayStartTimestamp, decayEndTimestamp, bidSignature, - commitmentSignature + commitmentSignature, + sharedSecretKey ); return commitmentIndex; @@ -332,10 +381,9 @@ contract TestPreConfCommitmentStore is Test { uint64 decayEndTimestamp, string memory txnHash, bytes memory bidSignature, - bytes memory commitmentSignature + bytes memory commitmentSignature, + bytes memory sharedSecretKey ) public { - - (PreConfCommitmentStore.PreConfCommitment memory commitment) = preConfCommitmentStore .getCommitment(index); @@ -347,7 +395,8 @@ contract TestPreConfCommitmentStore is Test { decayEndTimestamp, commitment.bidHash, bidSignature, - commitmentSignature + commitmentSignature, + sharedSecretKey ); bytes32[] memory commitments = preConfCommitmentStore.getCommitmentsByCommitter(commiterAddress); @@ -404,20 +453,23 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, _testCommitmentAliceBob.bidSignature, - _testCommitmentAliceBob.commitmentSignature + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey ); - PreConfCommitmentStore.PreConfCommitment - memory storedCommitment = preConfCommitmentStore.getCommitment( + PreConfCommitmentStore.EncrPreConfCommitment + memory storedCommitment = preConfCommitmentStore.getEncryptedCommitment( commitmentIndex ); - assertEq(storedCommitment.bid, _testCommitmentAliceBob.bid); - assertEq(storedCommitment.blockNumber, _testCommitmentAliceBob.blockNumber); - assertEq(storedCommitment.txnHash, _testCommitmentAliceBob.txnHash); - assertEq(storedCommitment.bidSignature, _testCommitmentAliceBob.bidSignature); + assertEq(storedCommitment.commitmentDigest, _testCommitmentAliceBob.commitmentDigest); assertEq(storedCommitment.commitmentSignature, _testCommitmentAliceBob.commitmentSignature); - assertEq(storedCommitment.decayEndTimeStamp, _testCommitmentAliceBob.decayEndTimestamp); - assertEq(storedCommitment.decayStartTimeStamp, _testCommitmentAliceBob.decayStartTimestamp); + // assertEq(storedCommitment.bid, _testCommitmentAliceBob.bid); + // assertEq(storedCommitment.blockNumber, _testCommitmentAliceBob.blockNumber); + // assertEq(storedCommitment.txnHash, _testCommitmentAliceBob.txnHash); + // assertEq(storedCommitment.bidSignature, _testCommitmentAliceBob.bidSignature); + // assertEq(storedCommitment.commitmentSignature, _testCommitmentAliceBob.commitmentSignature); + // assertEq(storedCommitment.decayEndTimeStamp, _testCommitmentAliceBob.decayEndTimestamp); + // assertEq(storedCommitment.decayStartTimeStamp, _testCommitmentAliceBob.decayStartTimestamp); } function test_InitiateSlash() public { @@ -445,21 +497,33 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, bidHash, - _bytesToHexString(_testCommitmentAliceBob.bidSignature) + _bytesToHexString(_testCommitmentAliceBob.bidSignature), + _bytesToHexString(_testCommitmentAliceBob.sharedSecretKey) ); // Verify that the commitment has not been used before - (bool commitmentUsed, , , , , , , , , , , , ) = preConfCommitmentStore + (bool commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(preConfHash); assert(commitmentUsed == false); - bytes32 index = preConfCommitmentStore.storeCommitment( + // bytes32 index = preConfCommitmentStore.storeCommitment( + // _testCommitmentAliceBob.bid, + // _testCommitmentAliceBob.blockNumber, + // _testCommitmentAliceBob.txnHash, + // _testCommitmentAliceBob.decayStartTimestamp, + // _testCommitmentAliceBob.decayEndTimestamp, + // _testCommitmentAliceBob.bidSignature, + // _testCommitmentAliceBob.commitmentSignature, + // _testCommitmentAliceBob.sharedSecretKey + // ); + bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, _testCommitmentAliceBob.bidSignature, - _testCommitmentAliceBob.commitmentSignature + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey ); providerRegistry.setPreconfirmationsContract( address(preConfCommitmentStore) @@ -468,10 +532,24 @@ contract TestPreConfCommitmentStore is Test { vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, commiter); + bytes32 index = openCommitment( + encryptedIndex, + _testCommitmentAliceBob.bid, + _testCommitmentAliceBob.blockNumber, + _testCommitmentAliceBob.txnHash, + _testCommitmentAliceBob.decayStartTimestamp, + _testCommitmentAliceBob.decayEndTimestamp, + _testCommitmentAliceBob.bidSignature, + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey + ); + uint256 window = blockTracker.getCurrentWindow(); vm.prank(feeRecipient); - preConfCommitmentStore.initiateSlash(index, 100); + preConfCommitmentStore.initiateSlash(window, index, 100); - (commitmentUsed, , , , , , , , , , , , ) = preConfCommitmentStore + (commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(index); // Verify that the commitment has been marked as used assert(commitmentUsed == true); @@ -503,30 +581,56 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, bidHash, - _bytesToHexString(_testCommitmentAliceBob.bidSignature) + _bytesToHexString(_testCommitmentAliceBob.bidSignature), + _bytesToHexString(_testCommitmentAliceBob.sharedSecretKey) ); // Verify that the commitment has not been used before - (bool commitmentUsed, , , , , , , , , , , , ) = preConfCommitmentStore + (bool commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(preConfHash); assert(commitmentUsed == false); - bytes32 index = preConfCommitmentStore.storeCommitment( + // bytes32 index = preConfCommitmentStore.storeCommitment( + // _testCommitmentAliceBob.bid, + // _testCommitmentAliceBob.blockNumber, + // _testCommitmentAliceBob.txnHash, + // _testCommitmentAliceBob.decayStartTimestamp, + // _testCommitmentAliceBob.decayEndTimestamp, + // _testCommitmentAliceBob.bidSignature, + // _testCommitmentAliceBob.commitmentSignature, + // _testCommitmentAliceBob.sharedSecretKey + // ); + bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, _testCommitmentAliceBob.bidSignature, - _testCommitmentAliceBob.commitmentSignature + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey ); (address commiter, ) = makeAddrAndKey("bob"); vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, commiter); + bytes32 index = openCommitment( + encryptedIndex, + _testCommitmentAliceBob.bid, + _testCommitmentAliceBob.blockNumber, + _testCommitmentAliceBob.txnHash, + _testCommitmentAliceBob.decayStartTimestamp, + _testCommitmentAliceBob.decayEndTimestamp, + _testCommitmentAliceBob.bidSignature, + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey + ); + uint256 window = blockTracker.getCurrentWindow(); vm.prank(feeRecipient); - preConfCommitmentStore.initiateReward(index, 100); + preConfCommitmentStore.initiateReward(window, index, 100); - (commitmentUsed, , , , , , , , , , , , ) = preConfCommitmentStore + (commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(index); // Verify that the commitment has been marked as used assert(commitmentUsed == true); @@ -559,36 +663,62 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, bidHash, - _bytesToHexString(_testCommitmentAliceBob.bidSignature) + _bytesToHexString(_testCommitmentAliceBob.bidSignature), + _bytesToHexString(_testCommitmentAliceBob.sharedSecretKey) ); // Verify that the commitment has not been used before - (bool commitmentUsed, , , , , , , , , , , , ) = preConfCommitmentStore + (bool commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(preConfHash); assert(commitmentUsed == false); - bytes32 index = preConfCommitmentStore.storeCommitment( + // bytes32 index = preConfCommitmentStore.storeCommitment( + // _testCommitmentAliceBob.bid, + // _testCommitmentAliceBob.blockNumber, + // _testCommitmentAliceBob.txnHash, + // _testCommitmentAliceBob.decayStartTimestamp, + // _testCommitmentAliceBob.decayEndTimestamp, + // _testCommitmentAliceBob.bidSignature, + // _testCommitmentAliceBob.commitmentSignature, + // _testCommitmentAliceBob.sharedSecretKey + // ); + bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, _testCommitmentAliceBob.bidSignature, - _testCommitmentAliceBob.commitmentSignature + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey ); (address commiter, ) = makeAddrAndKey("bob"); vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); + uint256 blockNumber = 2; + blockTracker.recordL1Block(blockNumber, commiter); + bytes32 index = openCommitment( + encryptedIndex, + _testCommitmentAliceBob.bid, + _testCommitmentAliceBob.blockNumber, + _testCommitmentAliceBob.txnHash, + _testCommitmentAliceBob.decayStartTimestamp, + _testCommitmentAliceBob.decayEndTimestamp, + _testCommitmentAliceBob.bidSignature, + _testCommitmentAliceBob.commitmentSignature, + _testCommitmentAliceBob.sharedSecretKey + ); + uint256 window = blockTracker.getCurrentWindow(); vm.prank(feeRecipient); - preConfCommitmentStore.initiateReward(index, 0); + preConfCommitmentStore.initiateReward(window, index, 0); - (commitmentUsed, , , , , , , , , , , , ) = preConfCommitmentStore + (commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(index); // Verify that the commitment has been marked as used assert(commitmentUsed == true); // commitmentHash value is internal to contract and not asserted - assert(bidderRegistry.bidderPrepaidBalances(bidder) == 2 ether); + assert(bidderRegistry.lockedFunds(bidder, window) == 2 ether); assert(bidderRegistry.providerAmount(commiter) == 0 ether); } diff --git a/test/ProviderRegistryTest.sol b/test/ProviderRegistryTest.sol index b3da8d3..3ff5d43 100644 --- a/test/ProviderRegistryTest.sol +++ b/test/ProviderRegistryTest.sol @@ -5,6 +5,7 @@ import "forge-std/Test.sol"; import {ProviderRegistry} from "../contracts/ProviderRegistry.sol"; import {BidderRegistry} from "../contracts/BidderRegistry.sol"; import {PreConfCommitmentStore} from "../contracts/PreConfirmations.sol"; +import {BlockTracker} from "../contracts/BlockTracker.sol"; contract ProviderRegistryTest is Test { uint256 testNumber; @@ -15,7 +16,7 @@ contract ProviderRegistryTest is Test { address internal feeRecipient; BidderRegistry bidderRegistry; PreConfCommitmentStore preConfCommitmentStore; - + BlockTracker blockTracker; event ProviderRegistered(address indexed provider, uint256 stakedAmount); function setUp() public { @@ -30,8 +31,8 @@ contract ProviderRegistryTest is Test { feePercent, address(this) ); - - bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this)); + blockTracker = new BlockTracker(address(this)); + bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this), address(blockTracker)); preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry From d47dc9854c355c0b02c51b6bf6835d5e06db0ff0 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Thu, 28 Mar 2024 17:51:44 +0100 Subject: [PATCH 06/24] clean up --- contracts/BidderRegistry.sol | 17 +------------ contracts/BlockTracker.sol | 37 +++++++++++++++++++++------ contracts/Oracle.sol | 3 +-- contracts/PreConfirmations.sol | 21 ++++++++++++++++ contracts/ProviderRegistry.sol | 12 ++++++--- test/BidderRegistryTest.sol | 8 ------ test/OracleTest.sol | 1 - test/PreConfirmationConfTest.sol | 43 +++----------------------------- 8 files changed, 63 insertions(+), 79 deletions(-) diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index 2f2d88c..6dc82f8 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -5,7 +5,6 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IBidderRegistry} from "./interfaces/IBidderRegistry.sol"; import {IBlockTracker} from "./interfaces/IBlockTracker.sol"; -import "forge-std/console.sol"; /// @title Bidder Registry /// @author Kartik Chopra @@ -30,6 +29,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /// @dev Address of the pre-confirmations contract address public preConfirmationsContract; + /// @dev Block tracker contract IBlockTracker public blockTrackerContract; /// @dev Fee recipient @@ -38,9 +38,6 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /// @dev Mapping for if bidder is registered mapping(address => bool) public bidderRegistered; - /// @dev Mapping from bidder addresses to their prepayed amount - // mapping(address => uint256) public bidderPrepaidBalances; - // Mapping from bidder addresses and window numbers to their locked funds mapping(address => mapping(uint256 => uint256)) public lockedFunds; @@ -175,7 +172,6 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { address bidder, uint256 window ) external view returns (uint256) { - // return bidderPrepaidBalances[bidder]; return lockedFunds[bidder][window]; } @@ -216,7 +212,6 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { lockedFunds[bidState.bidder][windowToSettle] += bidState.bidAmt - decayedAmt; - // bidderPrepaidBalances[bidState.bidder] += bidState.bidAmt - decayedAmt; BidPayment[commitmentDigest].state = State.Withdrawn; BidPayment[commitmentDigest].bidAmt = 0; @@ -301,16 +296,6 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { require(success, "couldn't transfer to provider"); } - // function withdrawPrepaidAmount(address payable bidder) external nonReentrant { - // uint256 prepaidAmount = bidderPrepaidBalances[bidder]; - // bidderPrepaidBalances[bidder] = 0; - // require(msg.sender == bidder, "only bidder can unprepay"); - // require(prepaidAmount > 0, "bidder prepaid Amount is zero"); - - // (bool success, ) = bidder.call{value: prepaidAmount}(""); - // require(success, "couldn't transfer prepay to bidder"); - // } - function withdrawBidderAmountFromWindow( address payable bidder, uint256 window diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol index b3a5512..28bf847 100644 --- a/contracts/BlockTracker.sol +++ b/contracts/BlockTracker.sol @@ -2,9 +2,15 @@ pragma solidity ^0.8.20; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; +/** + * @title BlockTracker + * @dev A contract that tracks Ethereum blocks and their winners. + */ contract BlockTracker is Ownable { + /// @dev Event emitted when a new L1 block is tracked. event NewL1Block(uint256 indexed blockNumber, address indexed winner); + /// @dev Event emitted when a new window is created. event NewWindow(uint256 indexed window); uint256 public currentWindow; @@ -12,28 +18,44 @@ contract BlockTracker is Ownable { uint256 public lastL1BlockNumber; address public lastL1BlockWinner; - constructor( - address _owner - ) Ownable() { + /** + * @dev Initializes the BlockTracker contract with the specified owner. + * @param _owner The address of the contract owner. + */ + constructor(address _owner) Ownable() { _transferOwnership(_owner); } + /** + * @dev Returns the number of the last L1 block recorded. + * @return The number of the last L1 block recorded. + */ function getLastL1BlockNumber() external view returns (uint256) { return lastL1BlockNumber; } + /** + * @dev Returns the winner of the last L1 block recorded. + * @return The address of the winner of the last L1 block recorded. + */ function getLastL1BlockWinner() external view returns (address) { return lastL1BlockWinner; } + /** + * @dev Returns the current window number. + * @return The current window number. + */ function getCurrentWindow() external view returns (uint256) { return currentWindow; } - function recordL1Block( - uint256 _blockNumber, - address _winner - ) external onlyOwner { + /** + * @dev Records a new L1 block and its winner. + * @param _blockNumber The number of the new L1 block. + * @param _winner The address of the winner of the new L1 block. + */ + function recordL1Block(uint256 _blockNumber, address _winner) external onlyOwner { lastL1BlockNumber = _blockNumber; lastL1BlockWinner = _winner; emit NewL1Block(_blockNumber, _winner); @@ -41,7 +63,6 @@ contract BlockTracker is Ownable { if (newWindow > currentWindow) { // We've entered a new window currentWindow = newWindow; - emit NewWindow(currentWindow); } } diff --git a/contracts/Oracle.sol b/contracts/Oracle.sol index 7ac6def..4058920 100644 --- a/contracts/Oracle.sol +++ b/contracts/Oracle.sol @@ -20,8 +20,6 @@ contract Oracle is Ownable { /// @dev Maps builder names to their respective Ethereum addresses. mapping(string => address) public blockBuilderNameToAddress; - - // To shutup the compiler /// @dev Empty receive function to silence compiler warnings about missing payable functions. receive() external payable { @@ -38,6 +36,7 @@ contract Oracle is Ownable { /// @dev Reference to the PreConfCommitmentStore contract interface. IPreConfCommitmentStore private preConfContract; + /// @dev Reference to the BlockTracker contract interface. IBlockTracker private blockTrackerContract; /** diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 20ed8ce..40e6208 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -311,6 +311,11 @@ contract PreConfCommitmentStore is Ownable { commiterAddress = preConfHash.recover(commitmentSignature); } + /** + * @dev Get the index of a commitment. + * @param commitment The commitment to get the index for. + * @return The index of the commitment. + */ function getCommitmentIndex( PreConfCommitment memory commitment ) public pure returns (bytes32) { @@ -323,6 +328,11 @@ contract PreConfCommitmentStore is Ownable { ); } + /** + * @dev Get the index of an encrypted commitment. + * @param commitment The commitment to get the index for. + * @return The index of the commitment. + */ function getEncryptedCommitmentIndex( EncrPreConfCommitment memory commitment ) public pure returns (bytes32) { @@ -440,6 +450,12 @@ contract PreConfCommitmentStore is Ownable { return commitmentIndex; } + /** + * @dev Store an encrypted commitment. + * @param commitmentDigest The digest of the commitment. + * @param commitmentSignature The signature of the commitment. + * @return commitmentIndex The index of the stored commitment + */ function storeEncryptedCommitment( bytes32 commitmentDigest, bytes memory commitmentSignature @@ -516,6 +532,11 @@ contract PreConfCommitmentStore is Ownable { return commitments[commitmentIndex]; } + /** + * @dev Get a commitments' enclosed transaction by its commitmentIndex. + * @param commitmentIndex The index of the commitment. + * @return txnHash The transaction hash. + */ function getEncryptedCommitment( bytes32 commitmentIndex ) public view returns (EncrPreConfCommitment memory) { diff --git a/contracts/ProviderRegistry.sol b/contracts/ProviderRegistry.sol index a3cd84f..0aea024 100644 --- a/contracts/ProviderRegistry.sol +++ b/contracts/ProviderRegistry.sol @@ -5,7 +5,6 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {PreConfCommitmentStore} from "./PreConfirmations.sol"; import {IProviderRegistry} from "./interfaces/IProviderRegistry.sol"; -import "forge-std/console.sol"; /// @title Provider Registry /// @author Kartik Chopra @@ -116,7 +115,6 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { function registerAndStake() public payable { require(!providerRegistered[msg.sender], "Provider already registered"); require(msg.value >= minStake, "Insufficient stake"); - console.log(msg.sender); providerStakes[msg.sender] = msg.value; providerRegistered[msg.sender] = true; @@ -148,6 +146,7 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { * @param amt The amount to slash from the provider's stake. * @param provider The address of the provider. * @param bidder The address to transfer the slashed funds to. + * @param residualBidPercentAfterDecay The residual bid percent after decay. */ function slash( uint256 amt, @@ -156,8 +155,6 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { uint256 residualBidPercentAfterDecay ) external nonReentrant onlyPreConfirmationEngine { uint256 residualAmt = (amt * residualBidPercentAfterDecay * PRECISION) / PERCENT; - console.log(residualAmt); - console.log(providerStakes[provider]); require(providerStakes[provider] >= residualAmt, "Insufficient funds to slash"); providerStakes[provider] -= residualAmt; @@ -191,12 +188,19 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { feePercent = newFeePercent; } + /** + * @dev Reward funds to the fee receipt. + */ function withdrawFeeRecipientAmount() external nonReentrant { feeRecipientAmount = 0; (bool successFee, ) = feeRecipient.call{value: feeRecipientAmount}(""); require(successFee, "Couldn't transfer to fee Recipient"); } + /** + * @dev Withdraw funds to the bidder. + * @param bidder The address of the bidder. + */ function withdrawBidderAmount(address bidder) external nonReentrant { require(bidderAmount[bidder] > 0, "Bidder Amount is zero"); diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index f39e854..7aaf8b0 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -160,7 +160,6 @@ contract BidderRegistryTest is Test { assertEq(bidderRegistry.getFeeRecipientAmount(), 100000000000000000); assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 1 ether); - // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 1 ether); } function test_shouldRetrieveFundsWithoutFeeRecipient() public { @@ -180,7 +179,6 @@ contract BidderRegistryTest is Test { blockTracker.recordL1Block(blockNumber, provider); bytes32 bidID = keccak256("1234"); bidderRegistry.OpenBid(bidID, 1 ether, bidder); - // bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); uint256 feerecipientValueAfter = bidderRegistry.feeRecipientAmount(); @@ -190,7 +188,6 @@ contract BidderRegistryTest is Test { assertEq(feerecipientValueAfter, feerecipientValueBefore); assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 1 ether); - // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 1 ether); } function testFail_shouldRetrieveFundsNotPreConf() public { @@ -202,7 +199,6 @@ contract BidderRegistryTest is Test { vm.expectRevert(bytes("")); bytes32 bidID = keccak256("1234"); bidderRegistry.OpenBid(bidID, 1 ether, bidder); - // bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); } @@ -220,7 +216,6 @@ contract BidderRegistryTest is Test { vm.prank(address(this)); bytes32 bidID = keccak256("1234"); bidderRegistry.OpenBid(bidID, 3 ether, bidder); - // bidderRegistry.LockBidFunds(bidID, 3 ether, bidder); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); } @@ -233,7 +228,6 @@ contract BidderRegistryTest is Test { address provider = vm.addr(4); uint256 balanceBefore = feeRecipient.balance; bytes32 bidID = keccak256("1234"); - // bidderRegistry.LockBidFunds(bidID, 1 ether, bidder); uint256 blockNumber = 2; blockTracker.recordL1Block(blockNumber, provider); @@ -264,7 +258,6 @@ contract BidderRegistryTest is Test { blockTracker.recordL1Block(blockNumber, provider); bidderRegistry.OpenBid(bidID, 2 ether, bidder); - // bidderRegistry.LockBidFunds(bidID, 2 ether, bidder); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); bidderRegistry.withdrawProviderAmount(payable(provider)); @@ -294,7 +287,6 @@ contract BidderRegistryTest is Test { uint256 blockNumber = 2; blockTracker.recordL1Block(blockNumber, provider); - // bidderRegistry.LockBidFunds(bidID, 2 ether, bidder); bidderRegistry.OpenBid(bidID, 2 ether, bidder); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); vm.prank(bidderRegistry.owner()); diff --git a/test/OracleTest.sol b/test/OracleTest.sol index 0ec15d4..0a6c5d1 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -390,7 +390,6 @@ contract OracleTest is Test { assertEq(providerRegistry.checkStake(provider) , 250 ether); assertEq(bidderRegistry.lockedFunds(bidder, currentWindow), 250 ether); - // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether); } diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index c45ad4a..de5bab2 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -225,10 +225,10 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.sharedSecretKey ); - // Step 4: Move to the next window + // Step 3: Move to the next window blockTracker.recordL1Block(2, address(this)); - // Step 5: Open the commitment + // Step 4: Open the commitment bytes32 index = openCommitment( encryptedIndex, _testCommitmentAliceBob.bid, @@ -241,7 +241,7 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.sharedSecretKey ); - // Step 3: Verify the stored commitment + // Step 5: Verify the stored commitment verifyStoredCommitment( index, _testCommitmentAliceBob.bid, @@ -463,13 +463,6 @@ contract TestPreConfCommitmentStore is Test { assertEq(storedCommitment.commitmentDigest, _testCommitmentAliceBob.commitmentDigest); assertEq(storedCommitment.commitmentSignature, _testCommitmentAliceBob.commitmentSignature); - // assertEq(storedCommitment.bid, _testCommitmentAliceBob.bid); - // assertEq(storedCommitment.blockNumber, _testCommitmentAliceBob.blockNumber); - // assertEq(storedCommitment.txnHash, _testCommitmentAliceBob.txnHash); - // assertEq(storedCommitment.bidSignature, _testCommitmentAliceBob.bidSignature); - // assertEq(storedCommitment.commitmentSignature, _testCommitmentAliceBob.commitmentSignature); - // assertEq(storedCommitment.decayEndTimeStamp, _testCommitmentAliceBob.decayEndTimestamp); - // assertEq(storedCommitment.decayStartTimeStamp, _testCommitmentAliceBob.decayStartTimestamp); } function test_InitiateSlash() public { @@ -505,16 +498,6 @@ contract TestPreConfCommitmentStore is Test { (bool commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(preConfHash); assert(commitmentUsed == false); - // bytes32 index = preConfCommitmentStore.storeCommitment( - // _testCommitmentAliceBob.bid, - // _testCommitmentAliceBob.blockNumber, - // _testCommitmentAliceBob.txnHash, - // _testCommitmentAliceBob.decayStartTimestamp, - // _testCommitmentAliceBob.decayEndTimestamp, - // _testCommitmentAliceBob.bidSignature, - // _testCommitmentAliceBob.commitmentSignature, - // _testCommitmentAliceBob.sharedSecretKey - // ); bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, @@ -589,16 +572,6 @@ contract TestPreConfCommitmentStore is Test { (bool commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(preConfHash); assert(commitmentUsed == false); - // bytes32 index = preConfCommitmentStore.storeCommitment( - // _testCommitmentAliceBob.bid, - // _testCommitmentAliceBob.blockNumber, - // _testCommitmentAliceBob.txnHash, - // _testCommitmentAliceBob.decayStartTimestamp, - // _testCommitmentAliceBob.decayEndTimestamp, - // _testCommitmentAliceBob.bidSignature, - // _testCommitmentAliceBob.commitmentSignature, - // _testCommitmentAliceBob.sharedSecretKey - // ); bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, @@ -671,16 +644,6 @@ contract TestPreConfCommitmentStore is Test { (bool commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(preConfHash); assert(commitmentUsed == false); - // bytes32 index = preConfCommitmentStore.storeCommitment( - // _testCommitmentAliceBob.bid, - // _testCommitmentAliceBob.blockNumber, - // _testCommitmentAliceBob.txnHash, - // _testCommitmentAliceBob.decayStartTimestamp, - // _testCommitmentAliceBob.decayEndTimestamp, - // _testCommitmentAliceBob.bidSignature, - // _testCommitmentAliceBob.commitmentSignature, - // _testCommitmentAliceBob.sharedSecretKey - // ); bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, From 93d5cd271224325b188c14c2d74a84eed00b3747 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Thu, 28 Mar 2024 17:51:56 +0100 Subject: [PATCH 07/24] clean up --- contracts/interfaces/IBidderRegistry.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/interfaces/IBidderRegistry.sol b/contracts/interfaces/IBidderRegistry.sol index 98aca88..cabc7f8 100644 --- a/contracts/interfaces/IBidderRegistry.sol +++ b/contracts/interfaces/IBidderRegistry.sol @@ -27,8 +27,6 @@ interface IBidderRegistry { function prepay() external payable; - // function LockBidFunds(bytes32 commitmentDigest, uint64 bid, address bidder) external; - function OpenBid(bytes32 commitmentDigest, uint64 bid, address bidder) external; function getAllowance(address bidder, uint256 window) external view returns (uint256); From b16e8dbad0c31910766c43767784c476dbbec6fe Mon Sep 17 00:00:00 2001 From: Mikelle Date: Thu, 28 Mar 2024 21:24:18 +0100 Subject: [PATCH 08/24] added checker for the com opening --- contracts/BidderRegistry.sol | 9 ++++++- contracts/BlockTracker.sol | 35 ++++++++++++++++++++++++++ contracts/Oracle.sol | 2 -- contracts/PreConfirmations.sol | 28 +++++++++++++++------ contracts/interfaces/IBlockTracker.sol | 14 +++++++++++ test/BidderRegistryTest.sol | 18 ++++++------- test/OracleTest.sol | 18 ++++++------- test/PreConfirmationConfTest.sol | 13 +++++++--- test/ProviderRegistryTest.sol | 1 + 9 files changed, 106 insertions(+), 32 deletions(-) diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index 6dc82f8..0003051 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -249,12 +249,19 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { ) external onlyPreConfirmationEngine { BidState memory bidState = BidPayment[commitmentDigest]; if (bidState.state == State.Undefined) { + uint256 currentWindow = blockTrackerContract.getCurrentWindow(); + // @todo delete this, when oracle will do the calculation + // bidder cannot bid more than allowed for the round + uint256 numberOfRounds = blockTrackerContract.getBlocksPerWindow(); + uint256 windowAmount = lockedFunds[bidder][currentWindow] / numberOfRounds; + if (windowAmount < bid) { + bid = uint64(windowAmount); + } BidPayment[commitmentDigest] = BidState({ state: State.PreConfirmed, bidder: bidder, bidAmt: bid }); - uint256 currentWindow = blockTrackerContract.getCurrentWindow(); lockedFunds[bidder][currentWindow] -= bid; } } diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol index 28bf847..8f36919 100644 --- a/contracts/BlockTracker.sol +++ b/contracts/BlockTracker.sol @@ -18,6 +18,9 @@ contract BlockTracker is Ownable { uint256 public lastL1BlockNumber; address public lastL1BlockWinner; + // Mapping from block number to the winner's address + mapping(uint256 => address) public blockWinners; + /** * @dev Initializes the BlockTracker contract with the specified owner. * @param _owner The address of the contract owner. @@ -42,6 +45,21 @@ contract BlockTracker is Ownable { return lastL1BlockWinner; } + /** + * @dev Returns the number of blocks per window. + * @return The number of blocks per window. + */ + function getBlocksPerWindow() external view returns (uint256) { + return blocksPerWindow; + } + + /** + * @dev Sets the number of blocks per window. + * @param _blocksPerWindow The new number of blocks per window. + */ + function setBlocksPerWindow(uint256 _blocksPerWindow) external onlyOwner { + blocksPerWindow = _blocksPerWindow; + } /** * @dev Returns the current window number. * @return The current window number. @@ -58,6 +76,7 @@ contract BlockTracker is Ownable { function recordL1Block(uint256 _blockNumber, address _winner) external onlyOwner { lastL1BlockNumber = _blockNumber; lastL1BlockWinner = _winner; + recordBlockWinner(_blockNumber, _winner); emit NewL1Block(_blockNumber, _winner); uint256 newWindow = (_blockNumber - 1) / blocksPerWindow + 1; if (newWindow > currentWindow) { @@ -67,6 +86,22 @@ contract BlockTracker is Ownable { } } + // Function to record a new block winner + function recordBlockWinner(uint256 blockNumber, address winner) internal { + // Check if the block number is valid (not 0) + require(blockNumber != 0, "Invalid block number"); + + // Check if the winner address is valid (not the zero address) + require(winner != address(0), "Invalid winner address"); + + blockWinners[blockNumber] = winner; + } + + // Function to get the winner of a specific block + function getBlockWinner(uint256 blockNumber) external view returns (address) { + return blockWinners[blockNumber]; + } + /** * @dev Fallback function to revert all calls, ensuring no unintended interactions. */ diff --git a/contracts/Oracle.sol b/contracts/Oracle.sol index 4058920..6f03c74 100644 --- a/contracts/Oracle.sol +++ b/contracts/Oracle.sol @@ -47,11 +47,9 @@ contract Oracle is Ownable { constructor( address _preConfContract, address _blockTrackerContract, - // uint256 _nextRequestedBlockNumber, address _owner ) Ownable() { preConfContract = IPreConfCommitmentStore(_preConfContract); - // nextRequestedBlockNumber = _nextRequestedBlockNumber; blockTrackerContract = IBlockTracker(_blockTrackerContract); _transferOwnership(_owner); } diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 40e6208..620f758 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -6,6 +6,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {IProviderRegistry} from "./interfaces/IProviderRegistry.sol"; import {IBidderRegistry} from "./interfaces/IBidderRegistry.sol"; +import {IBlockTracker} from "./interfaces/IBlockTracker.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import "forge-std/console.sol"; @@ -50,6 +51,9 @@ contract PreConfCommitmentStore is Ownable { /// @dev Address of bidderRegistry IBidderRegistry public bidderRegistry; + /// @dev Address of blockTracker + IBlockTracker public blockTracker; + /// @dev Mapping from provider to commitments count mapping(address => uint256) public commitmentsCount; @@ -143,16 +147,19 @@ contract PreConfCommitmentStore is Ownable { * @dev Initializes the contract with the specified registry addresses, oracle, name, and version. * @param _providerRegistry The address of the provider registry. * @param _bidderRegistry The address of the bidder registry. + * @param _blockTracker The address of the block tracker. * @param _oracle The address of the oracle. * @param _owner Owner of the contract, explicitly needed since contract is deployed w/ create2 factory. */ constructor( address _providerRegistry, address _bidderRegistry, + address _blockTracker, address _oracle, address _owner ) { oracle = _oracle; + blockTracker = IBlockTracker(_blockTracker); providerRegistry = IProviderRegistry(_providerRegistry); bidderRegistry = IBidderRegistry(_bidderRegistry); _transferOwnership(_owner); @@ -346,13 +353,17 @@ contract PreConfCommitmentStore is Ownable { } /** - * @dev Store a commitment. - * @param bid The bid amount. - * @param blockNumber The block number. - * @param txnHash The transaction hash. - * @param bidSignature The signature of the bid. - * @param commitmentSignature The signature of the commitment. - * @return commitmentIndex The index of the stored commitment + @dev Open a commitment + @param encryptedCommitmentIndex The index of the encrypted commitment + @param bid The bid amount + @param blockNumber The block number + @param txnHash The transaction hash + @param decayStartTimeStamp The start time of the decay + @param decayEndTimeStamp The end time of the decay + @param bidSignature The signature of the bid + @param commitmentSignature The signature of the commitment + @param sharedSecretKey The shared secret key + @return commitmentIndex The index of the stored commitment */ function openCommitment( bytes32 encryptedCommitmentIndex, @@ -401,6 +412,9 @@ contract PreConfCommitmentStore is Ownable { decayStartTimeStamp < decayEndTimeStamp, "Invalid decay time" ); + + address winner = blockTracker.getBlockWinner(blockNumber); + require(msg.sender == winner || msg.sender == bidderAddress, "Caller is not a winner provider or bidder"); PreConfCommitment memory newCommitment = PreConfCommitment( false, diff --git a/contracts/interfaces/IBlockTracker.sol b/contracts/interfaces/IBlockTracker.sol index 1261b14..dadab1f 100644 --- a/contracts/interfaces/IBlockTracker.sol +++ b/contracts/interfaces/IBlockTracker.sol @@ -15,6 +15,20 @@ interface IBlockTracker { /// @return The current window number. function getCurrentWindow() external view returns (uint256); + /// @notice Retrieves the number of blocks per window. + /// @return The number of blocks per window. + function getBlocksPerWindow() external view returns (uint256); + + /// @notice Sets the number of blocks per window. + /// @param _blocksPerWindow The new number of blocks per window. + /// @dev Only callable by the owner. + function setBlocksPerWindow(uint256 _blocksPerWindow) external; + + /// @notice Retrieves the winner of a specific L1 block. + /// @param _blockNumber The block number of the L1 block. + /// @return The address of the winner of the L1 block. + function getBlockWinner(uint256 _blockNumber) external view returns (address); + /// @notice Records a new L1 block with its winner. /// @param _blockNumber The block number of the new L1 block. /// @param _winner The address of the winner of the new L1 block. diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index 7aaf8b0..c05b5a7 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -26,8 +26,8 @@ contract BidderRegistryTest is Test { bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this), address(blockTracker)); bidder = vm.addr(1); - vm.deal(bidder, 100 ether); - vm.deal(address(this), 100 ether); + vm.deal(bidder, 1000 ether); + vm.deal(address(this), 1000 ether); } function test_VerifyInitialContractState() public { @@ -144,7 +144,7 @@ contract BidderRegistryTest is Test { uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + bidderRegistry.prepay{value: 64 ether}(); address provider = vm.addr(4); uint256 blockNumber = 2; blockTracker.recordL1Block(blockNumber, provider); @@ -159,7 +159,7 @@ contract BidderRegistryTest is Test { assertEq(feeRecipientAmount, 100000000000000000); assertEq(bidderRegistry.getFeeRecipientAmount(), 100000000000000000); - assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 1 ether); + assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 63 ether); } function test_shouldRetrieveFundsWithoutFeeRecipient() public { @@ -172,7 +172,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + bidderRegistry.prepay{value: 64 ether}(); address provider = vm.addr(4); uint256 blockNumber = 2; @@ -187,7 +187,7 @@ contract BidderRegistryTest is Test { assertEq(providerAmount, 900000000000000000); assertEq(feerecipientValueAfter, feerecipientValueBefore); - assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 1 ether); + assertEq(bidderRegistry.lockedFunds(bidder, nextWindow), 63 ether); } function testFail_shouldRetrieveFundsNotPreConf() public { @@ -222,7 +222,7 @@ contract BidderRegistryTest is Test { function test_withdrawFeeRecipientAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + bidderRegistry.prepay{value: 64 ether}(); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; address provider = vm.addr(4); @@ -248,7 +248,7 @@ contract BidderRegistryTest is Test { function test_withdrawProviderAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); - bidderRegistry.prepay{value: 5 ether}(); + bidderRegistry.prepay{value: 128 ether}(); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; address provider = vm.addr(4); @@ -279,7 +279,7 @@ contract BidderRegistryTest is Test { bidderRegistry.setPreconfirmationsContract(address(this)); bidderRegistry.setNewFeeRecipient(address(0)); vm.prank(bidder); - bidderRegistry.prepay{value: 5 ether}(); + bidderRegistry.prepay{value: 128 ether}(); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; uint256 balanceBefore = address(bidder).balance; diff --git a/test/OracleTest.sol b/test/OracleTest.sol index 0a6c5d1..e0919da 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -75,6 +75,7 @@ contract OracleTest is Test { preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry address(bidderRegistry), // User Registry + address(blockTracker), // Block Tracker feeRecipient, // Oracle address(this) // Owner ); @@ -161,7 +162,7 @@ contract OracleTest is Test { function test_process_commitment_payment_payout() public { string memory txn = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; - uint64 blockNumber = 200; + uint64 blockNumber = 2; uint64 bid = 2; string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); @@ -223,7 +224,7 @@ contract OracleTest is Test { function test_process_commitment_slash_and_reward() public { string memory txn1 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; string memory txn2 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d09"; - uint64 blockNumber = 201; + uint64 blockNumber = 2; uint64 bid = 100; string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); @@ -312,7 +313,7 @@ contract OracleTest is Test { string memory txn2 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d09"; string memory txn3 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d10"; string memory txn4 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d11"; - uint64 blockNumber = 201; + uint64 blockNumber = 2; uint64 bid = 5; string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); @@ -360,7 +361,7 @@ contract OracleTest is Test { function test_process_commitment_and_return() public { string memory txn = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; - uint64 blockNumber = 200; + uint64 blockNumber = 2; uint64 bid = 2; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); @@ -386,10 +387,8 @@ contract OracleTest is Test { emit FundsRetrieved(commitment.commitmentHash, window, bid); oracle.unlockFunds(window, commitments); - uint256 currentWindow = blockTracker.getCurrentWindow(); - assertEq(providerRegistry.checkStake(provider) , 250 ether); - assertEq(bidderRegistry.lockedFunds(bidder, currentWindow), 250 ether); + assertEq(bidderRegistry.lockedFunds(bidder, window), 250 ether); } @@ -436,10 +435,10 @@ contract OracleTest is Test { commitmentHash, commitmentSignature ); - uint256 l1BlockNumber = 2; vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); - blockTracker.recordL1Block(l1BlockNumber, provider); + blockTracker.recordL1Block(blockNumber, provider); vm.stopPrank(); + vm.startPrank(provider); commitmentIndex = preConfCommitmentStore.openCommitment( encryptedCommitmentIndex, bid, @@ -451,6 +450,7 @@ contract OracleTest is Test { commitmentSignature, sharedSecretKey ); + vm.stopPrank(); return commitmentIndex; } diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index de5bab2..e5e3910 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -64,6 +64,7 @@ contract TestPreConfCommitmentStore is Test { preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry address(bidderRegistry), // User Registry + address(blockTracker), // Block Tracker feeRecipient, // Oracle address(this) // Owner ); @@ -230,6 +231,7 @@ contract TestPreConfCommitmentStore is Test { // Step 4: Open the commitment bytes32 index = openCommitment( + bidder, encryptedIndex, _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, @@ -329,6 +331,7 @@ contract TestPreConfCommitmentStore is Test { } function openCommitment( + address msgSender, bytes32 encryptedCommitmentIndex, uint64 bid, uint64 blockNumber, @@ -358,6 +361,7 @@ contract TestPreConfCommitmentStore is Test { _bytesToHexString(sharedSecretKey) ); + vm.prank(msgSender); bytes32 commitmentIndex = preConfCommitmentStore.openCommitment( encryptedCommitmentIndex, bid, @@ -518,6 +522,7 @@ contract TestPreConfCommitmentStore is Test { uint256 blockNumber = 2; blockTracker.recordL1Block(blockNumber, commiter); bytes32 index = openCommitment( + commiter, encryptedIndex, _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, @@ -586,9 +591,9 @@ contract TestPreConfCommitmentStore is Test { vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); - uint256 blockNumber = 2; - blockTracker.recordL1Block(blockNumber, commiter); + blockTracker.recordL1Block(_testCommitmentAliceBob.blockNumber, commiter); bytes32 index = openCommitment( + commiter, encryptedIndex, _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, @@ -658,9 +663,9 @@ contract TestPreConfCommitmentStore is Test { vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); - uint256 blockNumber = 2; - blockTracker.recordL1Block(blockNumber, commiter); + blockTracker.recordL1Block(_testCommitmentAliceBob.blockNumber, commiter); bytes32 index = openCommitment( + commiter, encryptedIndex, _testCommitmentAliceBob.bid, _testCommitmentAliceBob.blockNumber, diff --git a/test/ProviderRegistryTest.sol b/test/ProviderRegistryTest.sol index 3ff5d43..250f0db 100644 --- a/test/ProviderRegistryTest.sol +++ b/test/ProviderRegistryTest.sol @@ -37,6 +37,7 @@ contract ProviderRegistryTest is Test { preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry address(bidderRegistry), // User Registry + address(blockTracker), // Block Tracker feeRecipient, // Oracle address(this) // Owner ); From e0505387d410c6d49f8e6fd11096233fafbe931e Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 1 Apr 2024 14:44:11 +0200 Subject: [PATCH 09/24] updated NewL1Block event --- contracts/BlockTracker.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol index 8f36919..abad6a3 100644 --- a/contracts/BlockTracker.sol +++ b/contracts/BlockTracker.sol @@ -8,7 +8,7 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; */ contract BlockTracker is Ownable { /// @dev Event emitted when a new L1 block is tracked. - event NewL1Block(uint256 indexed blockNumber, address indexed winner); + event NewL1Block(uint256 indexed blockNumber, address indexed winner, uint256 indexed window); /// @dev Event emitted when a new window is created. event NewWindow(uint256 indexed window); @@ -77,13 +77,13 @@ contract BlockTracker is Ownable { lastL1BlockNumber = _blockNumber; lastL1BlockWinner = _winner; recordBlockWinner(_blockNumber, _winner); - emit NewL1Block(_blockNumber, _winner); uint256 newWindow = (_blockNumber - 1) / blocksPerWindow + 1; if (newWindow > currentWindow) { // We've entered a new window currentWindow = newWindow; emit NewWindow(currentWindow); } + emit NewL1Block(_blockNumber, _winner, currentWindow); } // Function to record a new block winner From ba27e8e3fef03646f980f1a7efc4726342851d7e Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 1 Apr 2024 15:05:09 +0200 Subject: [PATCH 10/24] updated event --- contracts/PreConfirmations.sol | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 620f758..1ae1bbd 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -90,6 +90,7 @@ contract PreConfCommitmentStore is Ownable { } event CommitmentStored( + bytes32 commitmentIndex, address bidder, address commiter, uint64 bid, @@ -113,6 +114,14 @@ contract PreConfCommitmentStore is Ownable { uint256 blockCommitedAt; } + event EncryptedCommitmentStored( + bytes32 commitmentIndex, + address commiter, + bytes32 commitmentDigest, + bytes commitmentSignature, + uint256 blockCommitedAt + ); + /// @dev Event to log successful verifications event SignatureVerified( address indexed signer, @@ -445,6 +454,7 @@ contract PreConfCommitmentStore is Ownable { bidderRegistry.OpenBid(commitmentDigest, bid, bidderAddress); emit CommitmentStored( + commitmentIndex, bidderAddress, commiterAddress, bid, @@ -497,6 +507,14 @@ contract PreConfCommitmentStore is Ownable { commitmentCount++; commitmentsCount[commiterAddress] += 1; + + emit EncryptedCommitmentStored( + commitmentIndex, + commiterAddress, + commitmentDigest, + commitmentSignature, + block.number + ); } return commitmentIndex; From 9222caeb8e88436aeca4d16bec3397e3c19598b7 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 1 Apr 2024 15:09:11 +0200 Subject: [PATCH 11/24] added indexed keywork to the events --- contracts/PreConfirmations.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 1ae1bbd..460289f 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -90,7 +90,7 @@ contract PreConfCommitmentStore is Ownable { } event CommitmentStored( - bytes32 commitmentIndex, + bytes32 indexed commitmentIndex, address bidder, address commiter, uint64 bid, @@ -115,7 +115,7 @@ contract PreConfCommitmentStore is Ownable { } event EncryptedCommitmentStored( - bytes32 commitmentIndex, + bytes32 indexed commitmentIndex, address commiter, bytes32 commitmentDigest, bytes commitmentSignature, From 1b68a9c214257ff79a8f54beb5de9d8de1305449 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Fri, 5 Apr 2024 13:15:41 +0200 Subject: [PATCH 12/24] fixed deployment script --- contracts/PreConfirmations.sol | 2 -- scripts/DeployScripts.s.sol | 9 ++++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 460289f..97d9967 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -9,8 +9,6 @@ import {IBidderRegistry} from "./interfaces/IBidderRegistry.sol"; import {IBlockTracker} from "./interfaces/IBlockTracker.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import "forge-std/console.sol"; - /** * @title PreConfCommitmentStore - A contract for managing preconfirmation commitments and bids. * @notice This contract allows bidders to make precommitments and bids and provides a mechanism for the oracle to verify and process them. diff --git a/scripts/DeployScripts.s.sol b/scripts/DeployScripts.s.sol index 5a0e08c..e431b80 100644 --- a/scripts/DeployScripts.s.sol +++ b/scripts/DeployScripts.s.sol @@ -48,13 +48,16 @@ contract DeployScript is Script, Create2Deployer { // Forge deploy with salt uses create2 proxy from https://github.com/primevprotocol/deterministic-deployment-proxy bytes32 salt = 0x8989000000000000000000000000000000000000000000000000000000000000; - BidderRegistry bidderRegistry = new BidderRegistry{salt: salt}(minStake, feeRecipient, feePercent, msg.sender); + BlockTracker blockTracker = new BlockTracker{salt: salt}(msg.sender); + console.log("BlockTracker deployed to:", address(blockTracker)); + + BidderRegistry bidderRegistry = new BidderRegistry{salt: salt}(minStake, feeRecipient, feePercent, msg.sender, address(blockTracker)); console.log("BidderRegistry deployed to:", address(bidderRegistry)); ProviderRegistry providerRegistry = new ProviderRegistry{salt: salt}(minStake, feeRecipient, feePercent, msg.sender); console.log("ProviderRegistry deployed to:", address(providerRegistry)); - PreConfCommitmentStore preConfCommitmentStore = new PreConfCommitmentStore{salt: salt}(address(providerRegistry), address(bidderRegistry), feeRecipient, msg.sender); + PreConfCommitmentStore preConfCommitmentStore = new PreConfCommitmentStore{salt: salt}(address(providerRegistry), address(bidderRegistry), address(blockTracker), feeRecipient, msg.sender); console.log("PreConfCommitmentStore deployed to:", address(preConfCommitmentStore)); providerRegistry.setPreconfirmationsContract(address(preConfCommitmentStore)); @@ -63,7 +66,7 @@ contract DeployScript is Script, Create2Deployer { bidderRegistry.setPreconfirmationsContract(address(preConfCommitmentStore)); console.log("BidderRegistry updated with PreConfCommitmentStore address:", address(preConfCommitmentStore)); - Oracle oracle = new Oracle{salt: salt}(address(preConfCommitmentStore), nextRequestedBlockNumber, msg.sender); + Oracle oracle = new Oracle{salt: salt}(address(preConfCommitmentStore), address(blockTracker), msg.sender); console.log("Oracle deployed to:", address(oracle)); preConfCommitmentStore.updateOracle(address(oracle)); From 43df01ee3c68947e71fb77520ec04a4c1386c107 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Sat, 6 Apr 2024 22:56:28 +0200 Subject: [PATCH 13/24] fixed deployment --- scripts/DeployScripts.s.sol | 1 + test/PreConfirmationConfTest.sol | 11 ----------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/scripts/DeployScripts.s.sol b/scripts/DeployScripts.s.sol index e431b80..e5ac616 100644 --- a/scripts/DeployScripts.s.sol +++ b/scripts/DeployScripts.s.sol @@ -6,6 +6,7 @@ import "contracts/ProviderRegistry.sol"; import "contracts/PreConfirmations.sol"; import "contracts/Oracle.sol"; import "contracts/Whitelist.sol"; +import "contracts/BlockTracker.sol"; // Deploy scripts should inherit this contract if they deploy using create2 deterministic addrs. contract Create2Deployer { diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index e5e3910..c544533 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -350,17 +350,6 @@ contract TestPreConfCommitmentStore is Test { decayEndTimestamp ); - bytes32 commitmentHash = preConfCommitmentStore.getPreConfHash( - txnHash, - bid, - blockNumber, - decayStartTimestamp, - decayEndTimestamp, - bidHash, - _bytesToHexString(bidSignature), - _bytesToHexString(sharedSecretKey) - ); - vm.prank(msgSender); bytes32 commitmentIndex = preConfCommitmentStore.openCommitment( encryptedCommitmentIndex, From 322c79f30e3eb900eec2aba7b8446b5b50f84c3c Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 8 Apr 2024 23:12:58 +0200 Subject: [PATCH 14/24] added current window = 1 --- contracts/BlockTracker.sol | 2 +- test/BidderRegistryTest.sol | 10 +++++----- test/OracleTest.sol | 8 ++++---- test/PreConfirmationConfTest.sol | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol index abad6a3..76228c7 100644 --- a/contracts/BlockTracker.sol +++ b/contracts/BlockTracker.sol @@ -13,7 +13,7 @@ contract BlockTracker is Ownable { /// @dev Event emitted when a new window is created. event NewWindow(uint256 indexed window); - uint256 public currentWindow; + uint256 public currentWindow = 1; uint256 public blocksPerWindow = 64; uint256 public lastL1BlockNumber; address public lastL1BlockWinner; diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index c05b5a7..dc78dce 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -146,7 +146,7 @@ contract BidderRegistryTest is Test { vm.prank(bidder); bidderRegistry.prepay{value: 64 ether}(); address provider = vm.addr(4); - uint256 blockNumber = 2; + uint256 blockNumber = 66; blockTracker.recordL1Block(blockNumber, provider); bidderRegistry.OpenBid(bidID, 1 ether, bidder); @@ -175,7 +175,7 @@ contract BidderRegistryTest is Test { bidderRegistry.prepay{value: 64 ether}(); address provider = vm.addr(4); - uint256 blockNumber = 2; + uint256 blockNumber = 66; blockTracker.recordL1Block(blockNumber, provider); bytes32 bidID = keccak256("1234"); bidderRegistry.OpenBid(bidID, 1 ether, bidder); @@ -228,7 +228,7 @@ contract BidderRegistryTest is Test { address provider = vm.addr(4); uint256 balanceBefore = feeRecipient.balance; bytes32 bidID = keccak256("1234"); - uint256 blockNumber = 2; + uint256 blockNumber = 66; blockTracker.recordL1Block(blockNumber, provider); bidderRegistry.OpenBid(bidID, 1 ether, bidder); @@ -254,7 +254,7 @@ contract BidderRegistryTest is Test { address provider = vm.addr(4); uint256 balanceBefore = address(provider).balance; bytes32 bidID = keccak256("1234"); - uint256 blockNumber = 2; + uint256 blockNumber = 66; blockTracker.recordL1Block(blockNumber, provider); bidderRegistry.OpenBid(bidID, 2 ether, bidder); @@ -284,7 +284,7 @@ contract BidderRegistryTest is Test { uint256 nextWindow = currentWindow + 1; uint256 balanceBefore = address(bidder).balance; bytes32 bidID = keccak256("1234"); - uint256 blockNumber = 2; + uint256 blockNumber = 66; blockTracker.recordL1Block(blockNumber, provider); bidderRegistry.OpenBid(bidID, 2 ether, bidder); diff --git a/test/OracleTest.sol b/test/OracleTest.sol index e0919da..3461851 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -162,7 +162,7 @@ contract OracleTest is Test { function test_process_commitment_payment_payout() public { string memory txn = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; - uint64 blockNumber = 2; + uint64 blockNumber = 66; uint64 bid = 2; string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); @@ -224,7 +224,7 @@ contract OracleTest is Test { function test_process_commitment_slash_and_reward() public { string memory txn1 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; string memory txn2 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d09"; - uint64 blockNumber = 2; + uint64 blockNumber = 66; uint64 bid = 100; string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); @@ -313,7 +313,7 @@ contract OracleTest is Test { string memory txn2 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d09"; string memory txn3 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d10"; string memory txn4 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d11"; - uint64 blockNumber = 2; + uint64 blockNumber = 66; uint64 bid = 5; string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); @@ -361,7 +361,7 @@ contract OracleTest is Test { function test_process_commitment_and_return() public { string memory txn = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; - uint64 blockNumber = 2; + uint64 blockNumber = 66; uint64 bid = 2; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index c544533..ea98b11 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -640,7 +640,7 @@ contract TestPreConfCommitmentStore is Test { assert(commitmentUsed == false); bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, - _testCommitmentAliceBob.blockNumber, + 66, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, @@ -652,12 +652,12 @@ contract TestPreConfCommitmentStore is Test { vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); - blockTracker.recordL1Block(_testCommitmentAliceBob.blockNumber, commiter); + blockTracker.recordL1Block(66, commiter); bytes32 index = openCommitment( commiter, encryptedIndex, _testCommitmentAliceBob.bid, - _testCommitmentAliceBob.blockNumber, + 66, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, @@ -678,8 +678,8 @@ contract TestPreConfCommitmentStore is Test { assert(bidderRegistry.lockedFunds(bidder, window) == 2 ether); assert(bidderRegistry.providerAmount(commiter) == 0 ether); } - } + function _bytesToHexString( bytes memory _bytes ) public pure returns (string memory) { From 5e3ba1a145f157db42f7fe6de9ecd1edcbed297b Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 15 Apr 2024 10:58:03 +0200 Subject: [PATCH 15/24] updated deploy script --- scripts/DeployScripts.s.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/DeployScripts.s.sol b/scripts/DeployScripts.s.sol index e5ac616..6373259 100644 --- a/scripts/DeployScripts.s.sol +++ b/scripts/DeployScripts.s.sol @@ -51,7 +51,8 @@ contract DeployScript is Script, Create2Deployer { BlockTracker blockTracker = new BlockTracker{salt: salt}(msg.sender); console.log("BlockTracker deployed to:", address(blockTracker)); - + blockTracker.setBlocksPerWindow(10); + console.log("BlockTracker updated with blocksPerWindow:", 10); BidderRegistry bidderRegistry = new BidderRegistry{salt: salt}(minStake, feeRecipient, feePercent, msg.sender, address(blockTracker)); console.log("BidderRegistry deployed to:", address(bidderRegistry)); From 2e7b7300887bf35ccf22a31dd61146d8a604ed49 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 15 Apr 2024 17:47:59 +0200 Subject: [PATCH 16/24] fixed commitment hash --- contracts/PreConfirmations.sol | 2 +- test/PreConfirmationConfTest.sol | 139 ++++++++++++++++--------------- 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 97d9967..c6e9f82 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -19,7 +19,7 @@ contract PreConfCommitmentStore is Ownable { /// @dev EIP-712 Type Hash for preconfirmation commitment bytes32 public constant EIP712_COMMITMENT_TYPEHASH = keccak256( - "PreConfCommitment(string txnHash,uint64 bid,uint64 blockNumber,uint64 decayStartTimeStamp,uint64 decayEndTimeStamp,string bidHash,string signature)" + "PreConfCommitment(string txnHash,uint64 bid,uint64 blockNumber,uint64 decayStartTimeStamp,uint64 decayEndTimeStamp,bytes32 bidHash,string signature,string sharedSecretKey)" ); /// @dev EIP-712 Type Hash for preconfirmation bid diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index ea98b11..ac78b8c 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -3,14 +3,13 @@ pragma solidity ^0.8.20; import "forge-std/Test.sol"; - import {PreConfCommitmentStore} from "../contracts/PreConfirmations.sol"; import "../contracts/ProviderRegistry.sol"; import "../contracts/BidderRegistry.sol"; import "../contracts/BlockTracker.sol"; import "forge-std/console.sol"; -contract TestPreConfCommitmentStore is Test { +contract TestPreConfCommitmentStore is Test { struct TestCommitment { uint64 bid; uint64 blockNumber; @@ -43,10 +42,10 @@ contract TestPreConfCommitmentStore is Test { 10, 20, 0xa0327970258c49b922969af74d60299a648c50f69a2d98d6ab43f32f64ac2100, - 0x668206f9c4d620188852ee94940d37c4829b3d99fb702e10cd1804989662980f, + 0x65618f8f9e46b8f0790c621ca2989cfe4c949594a4a3a81261baa682e8883840, hex"876c1216c232828be9fabb14981c8788cebdf6ed66e563c4a2ccc82a577d052543207aeeb158a32d8977736797ae250c63ef69a82cd85b727da21e20d030fb311b", - hex"88194da2231873946f5c05b8dc447c430fa7356996617e07d01c4eabebca553044c7e2220c5699f3ad57ff474a1df14ad6f7a8eb9891f57932270f0157c984361b", - abi.encodePacked(keccak256("0xsecret")) + hex"bfea9167927707ae7586ed3bba8565999f8b7ad874b2dd4f175caf81084c0d0a17f9599daf5b3f2773757408aa4b44875c95df0f4150cfb295f95273e1fefdd01b", + bytes("0xsecret") ); feePercent = 10; @@ -59,7 +58,13 @@ contract TestPreConfCommitmentStore is Test { address(this) ); blockTracker = new BlockTracker(address(this)); - bidderRegistry = new BidderRegistry(minStake, feeRecipient, feePercent, address(this), address(blockTracker)); + bidderRegistry = new BidderRegistry( + minStake, + feeRecipient, + feePercent, + address(this), + address(blockTracker) + ); preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry @@ -69,7 +74,9 @@ contract TestPreConfCommitmentStore is Test { address(this) // Owner ); - bidderRegistry.setPreconfirmationsContract(address(preConfCommitmentStore)); + bidderRegistry.setPreconfirmationsContract( + address(preConfCommitmentStore) + ); } function test_Initialize() public { @@ -86,9 +93,14 @@ contract TestPreConfCommitmentStore is Test { function test_storeEncryptedCommitment() public { // Step 1: Prepare the commitment information and signature - bytes32 commitmentDigest = keccak256(abi.encodePacked("commitment data")); + bytes32 commitmentDigest = keccak256( + abi.encodePacked("commitment data") + ); (address committer, uint256 committerPk) = makeAddrAndKey("committer"); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(committerPk, commitmentDigest); + (uint8 v, bytes32 r, bytes32 s) = vm.sign( + committerPk, + commitmentDigest + ); bytes memory commitmentSignature = abi.encodePacked(r, s, v); // Optional: Ensure the committer has enough ETH if needed for the operation @@ -96,18 +108,18 @@ contract TestPreConfCommitmentStore is Test { vm.prank(committer); // Step 2: Store the commitment - bytes32 commitmentIndex = preConfCommitmentStore.storeEncryptedCommitment( - commitmentDigest, - commitmentSignature - ); + bytes32 commitmentIndex = preConfCommitmentStore + .storeEncryptedCommitment(commitmentDigest, commitmentSignature); // Step 3: Verify the results // a. Check that the commitment index is correctly generated and not zero assert(commitmentIndex != bytes32(0)); // b. Retrieve the commitment by index and verify its properties - (PreConfCommitmentStore.EncrPreConfCommitment memory commitment) = - preConfCommitmentStore.getEncryptedCommitment(commitmentIndex); + PreConfCommitmentStore.EncrPreConfCommitment + memory commitment = preConfCommitmentStore.getEncryptedCommitment( + commitmentIndex + ); // c. Assertions to verify the stored commitment matches the input assertEq(commitment.commitmentUsed, false); @@ -116,7 +128,6 @@ contract TestPreConfCommitmentStore is Test { assertEq(commitment.commitmentSignature, commitmentSignature); } - function test_UpdateOracle() public { preConfCommitmentStore.updateOracle(feeRecipient); assertEq(preConfCommitmentStore.oracle(), feeRecipient); @@ -132,7 +143,10 @@ contract TestPreConfCommitmentStore is Test { function test_UpdateBidderRegistry() public { preConfCommitmentStore.updateBidderRegistry(feeRecipient); - assertEq(address(preConfCommitmentStore.bidderRegistry()), feeRecipient); + assertEq( + address(preConfCommitmentStore.bidderRegistry()), + feeRecipient + ); } function test_GetBidHash() public { @@ -143,10 +157,7 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp ); - assertEq( - bidHash, - _testCommitmentAliceBob.bidDigest - ); + assertEq(bidHash, _testCommitmentAliceBob.bidDigest); } function test_GetCommitmentDigest() public { @@ -160,9 +171,9 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.decayEndTimestamp ); - (uint8 v,bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); bytes memory signature = abi.encodePacked(r, s, v); - bytes memory sharedSecretKey = abi.encodePacked(keccak256("0xsecret")); + bytes memory sharedSecretKey = bytes("0xsecret"); bytes32 preConfHash = preConfCommitmentStore.getPreConfHash( _testCommitmentAliceBob.txnHash, @@ -174,18 +185,14 @@ contract TestPreConfCommitmentStore is Test { _bytesToHexString(signature), _bytesToHexString(sharedSecretKey) ); - assertEq( - preConfHash, - _testCommitmentAliceBob.commitmentDigest - ); + assertEq(preConfHash, _testCommitmentAliceBob.commitmentDigest); (, uint256 providerPk) = makeAddrAndKey("bob"); - ( v, r, s) = vm.sign(providerPk, preConfHash); + (v, r, s) = vm.sign(providerPk, preConfHash); signature = abi.encodePacked(r, s, v); console.logBytes(signature); } - function _bytes32ToHexString( bytes32 _bytes32 ) internal pure returns (string memory) { @@ -256,7 +263,8 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.sharedSecretKey ); - string memory commitmentTxnHash = preConfCommitmentStore.getTxnHashFromCommitment(index); + string memory commitmentTxnHash = preConfCommitmentStore + .getTxnHashFromCommitment(index); console.log(commitmentTxnHash); console.log(_testCommitmentAliceBob.txnHash); assertEq(commitmentTxnHash, _testCommitmentAliceBob.txnHash); @@ -325,7 +333,8 @@ contract TestPreConfCommitmentStore is Test { _bytesToHexString(sharedSecretKey) ); - bytes32 commitmentIndex = preConfCommitmentStore.storeEncryptedCommitment(commitmentHash, commitmentSignature); + bytes32 commitmentIndex = preConfCommitmentStore + .storeEncryptedCommitment(commitmentHash, commitmentSignature); return commitmentIndex; } @@ -342,14 +351,6 @@ contract TestPreConfCommitmentStore is Test { bytes memory commitmentSignature, bytes memory sharedSecretKey ) internal returns (bytes32) { - bytes32 bidHash = preConfCommitmentStore.getBidHash( - txnHash, - bid, - blockNumber, - decayStartTimestamp, - decayEndTimestamp - ); - vm.prank(msgSender); bytes32 commitmentIndex = preConfCommitmentStore.openCommitment( encryptedCommitmentIndex, @@ -377,23 +378,25 @@ contract TestPreConfCommitmentStore is Test { bytes memory commitmentSignature, bytes memory sharedSecretKey ) public { - (PreConfCommitmentStore.PreConfCommitment memory commitment) = preConfCommitmentStore - .getCommitment(index); + PreConfCommitmentStore.PreConfCommitment + memory commitment = preConfCommitmentStore.getCommitment(index); + + (, address commiterAddress) = preConfCommitmentStore + .verifyPreConfCommitment( + txnHash, + bid, + blockNumber, + decayStartTimestamp, + decayEndTimestamp, + commitment.bidHash, + bidSignature, + commitmentSignature, + sharedSecretKey + ); - (, address commiterAddress) = preConfCommitmentStore.verifyPreConfCommitment( - txnHash, - bid, - blockNumber, - decayStartTimestamp, - decayEndTimestamp, - commitment.bidHash, - bidSignature, - commitmentSignature, - sharedSecretKey - ); + bytes32[] memory commitments = preConfCommitmentStore + .getCommitmentsByCommitter(commiterAddress); - bytes32[] memory commitments = preConfCommitmentStore.getCommitmentsByCommitter(commiterAddress); - assert(commitments.length >= 1); assertEq( @@ -450,12 +453,17 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.sharedSecretKey ); PreConfCommitmentStore.EncrPreConfCommitment - memory storedCommitment = preConfCommitmentStore.getEncryptedCommitment( - commitmentIndex - ); - - assertEq(storedCommitment.commitmentDigest, _testCommitmentAliceBob.commitmentDigest); - assertEq(storedCommitment.commitmentSignature, _testCommitmentAliceBob.commitmentSignature); + memory storedCommitment = preConfCommitmentStore + .getEncryptedCommitment(commitmentIndex); + + assertEq( + storedCommitment.commitmentDigest, + _testCommitmentAliceBob.commitmentDigest + ); + assertEq( + storedCommitment.commitmentSignature, + _testCommitmentAliceBob.commitmentSignature + ); } function test_InitiateSlash() public { @@ -465,7 +473,7 @@ contract TestPreConfCommitmentStore is Test { vm.deal(bidder, 5 ether); vm.prank(bidder); bidderRegistry.prepay{value: 2 ether}(); - + // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( _testCommitmentAliceBob.txnHash, @@ -533,7 +541,7 @@ contract TestPreConfCommitmentStore is Test { } // commitmentHash value is internal to contract and not asserted } - + function test_InitiateReward() public { // Assuming you have a stored commitment { @@ -541,7 +549,7 @@ contract TestPreConfCommitmentStore is Test { vm.deal(bidder, 5 ether); vm.prank(bidder); bidderRegistry.prepay{value: 2 ether}(); - + // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( _testCommitmentAliceBob.txnHash, @@ -605,7 +613,6 @@ contract TestPreConfCommitmentStore is Test { } } - function test_InitiateRewardFullyDecayed() public { // Assuming you have a stored commitment { @@ -613,7 +620,7 @@ contract TestPreConfCommitmentStore is Test { vm.deal(bidder, 5 ether); vm.prank(bidder); bidderRegistry.prepay{value: 2 ether}(); - + // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( _testCommitmentAliceBob.txnHash, @@ -679,7 +686,7 @@ contract TestPreConfCommitmentStore is Test { assert(bidderRegistry.providerAmount(commiter) == 0 ether); } } - + function _bytesToHexString( bytes memory _bytes ) public pure returns (string memory) { From af40c92794104611dbc36372d0f7c8bb242ab3a3 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Thu, 18 Apr 2024 01:20:53 +0200 Subject: [PATCH 17/24] set commitment used as true --- contracts/PreConfirmations.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index c6e9f82..619ed8c 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -445,6 +445,9 @@ contract PreConfCommitmentStore is Ownable { // Store commitment commitments[commitmentIndex] = newCommitment; + // Mark the encrypted commitment as used + encryptedCommitments[encryptedCommitmentIndex].commitmentUsed = true; + // Push pointers to other mappings providerCommitments[commiterAddress].push(commitmentIndex); blockCommitments[blockNumber].push(commitmentIndex); From ef8e4d453646f91d22c47218c7a36f4306ae2736 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Thu, 18 Apr 2024 18:30:06 +0200 Subject: [PATCH 18/24] added comments --- contracts/BidderRegistry.sol | 28 ++++++++++++++++++++++++++++ contracts/BlockTracker.sol | 22 ++++++++++++++++++---- contracts/PreConfirmations.sol | 3 +++ contracts/ProviderRegistry.sol | 4 ++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index 0003051..a7712dc 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -163,6 +163,19 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { ); } + /** + * @dev Prepay for a specific window. + * @param window The window for which the prepay is being made. + */ + function prepayAllowanceForSpecificWindow(uint256 window) external payable { + require(msg.value >= minAllowance, "Insufficient prepay"); + + bidderRegistered[msg.sender] = true; + lockedFunds[msg.sender][window] += msg.value; + + emit BidderRegistered(msg.sender, lockedFunds[msg.sender][window], window); + } + /** * @dev Check the prepay of a bidder. * @param bidder The address of the bidder. @@ -284,6 +297,9 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { feePercent = newFeePercent; } + /** + * @dev Withdraw funds to the fee recipient. + */ function withdrawFeeRecipientAmount() external nonReentrant { uint256 amount = feeRecipientAmount; feeRecipientAmount = 0; @@ -292,6 +308,10 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { require(successFee, "couldn't transfer to fee Recipient"); } + /** + * @dev Withdraw funds to the provider. + * @param provider The address of the provider. + */ function withdrawProviderAmount( address payable provider ) external nonReentrant { @@ -303,6 +323,10 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { require(success, "couldn't transfer to provider"); } + /** + * @dev Withdraw funds to the bidder. + * @param bidder The address of the bidder. + */ function withdrawBidderAmountFromWindow( address payable bidder, uint256 window @@ -327,6 +351,10 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { emit BidderWithdrawal(bidder, window, amount); } + /** + * @dev Withdraw protocol fee. + * @param bidder The address of the bidder. + */ function withdrawProtocolFee( address payable bidder ) external onlyOwner nonReentrant { diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol index 76228c7..eef35b6 100644 --- a/contracts/BlockTracker.sol +++ b/contracts/BlockTracker.sol @@ -8,11 +8,18 @@ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; */ contract BlockTracker is Ownable { /// @dev Event emitted when a new L1 block is tracked. - event NewL1Block(uint256 indexed blockNumber, address indexed winner, uint256 indexed window); + event NewL1Block( + uint256 indexed blockNumber, + address indexed winner, + uint256 indexed window + ); /// @dev Event emitted when a new window is created. event NewWindow(uint256 indexed window); + /// @dev Event emitted when the number of blocks per window is updated. + event NewBlocksPerWindow(uint256 blocksPerWindow); + uint256 public currentWindow = 1; uint256 public blocksPerWindow = 64; uint256 public lastL1BlockNumber; @@ -59,6 +66,8 @@ contract BlockTracker is Ownable { */ function setBlocksPerWindow(uint256 _blocksPerWindow) external onlyOwner { blocksPerWindow = _blocksPerWindow; + + emit NewBlocksPerWindow(blocksPerWindow); } /** * @dev Returns the current window number. @@ -73,7 +82,10 @@ contract BlockTracker is Ownable { * @param _blockNumber The number of the new L1 block. * @param _winner The address of the winner of the new L1 block. */ - function recordL1Block(uint256 _blockNumber, address _winner) external onlyOwner { + function recordL1Block( + uint256 _blockNumber, + address _winner + ) external onlyOwner { lastL1BlockNumber = _blockNumber; lastL1BlockWinner = _winner; recordBlockWinner(_blockNumber, _winner); @@ -98,7 +110,9 @@ contract BlockTracker is Ownable { } // Function to get the winner of a specific block - function getBlockWinner(uint256 blockNumber) external view returns (address) { + function getBlockWinner( + uint256 blockNumber + ) external view returns (address) { return blockWinners[blockNumber]; } @@ -116,4 +130,4 @@ contract BlockTracker is Ownable { receive() external payable { revert("Invalid call"); } -} \ No newline at end of file +} diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 619ed8c..48a7e41 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -87,6 +87,7 @@ contract PreConfCommitmentStore is Ownable { bytes sharedSecretKey; } + /// @dev Event to log successful commitment storage event CommitmentStored( bytes32 indexed commitmentIndex, address bidder, @@ -104,6 +105,7 @@ contract PreConfCommitmentStore is Ownable { bytes sharedSecretKey ); + /// @dev Struct for all the information around encrypted preconfirmations commitment struct EncrPreConfCommitment { bool commitmentUsed; address commiter; @@ -112,6 +114,7 @@ contract PreConfCommitmentStore is Ownable { uint256 blockCommitedAt; } + /// @dev Event to log successful encrypted commitment storage event EncryptedCommitmentStored( bytes32 indexed commitmentIndex, address commiter, diff --git a/contracts/ProviderRegistry.sol b/contracts/ProviderRegistry.sol index 0aea024..baafe2a 100644 --- a/contracts/ProviderRegistry.sol +++ b/contracts/ProviderRegistry.sol @@ -210,6 +210,10 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { require(success, "Couldn't transfer to bidder"); } + /** + * @dev Withdraw staked amount for the provider. + * @param provider The address of the provider. + */ function withdrawStakedAmount( address payable provider ) external nonReentrant { From a5276c18285b9f0d248688e133fa049a570af801 Mon Sep 17 00:00:00 2001 From: Alok Date: Fri, 19 Apr 2024 18:22:31 +0530 Subject: [PATCH 19/24] fix: restructure contracts and remove unused functions --- contracts/BidderRegistry.sol | 55 ++-- contracts/BlockTracker.sol | 58 ++-- contracts/Oracle.sol | 47 +-- contracts/PreConfirmations.sol | 16 +- contracts/ProviderRegistry.sol | 2 - contracts/interfaces/IBidderRegistry.sol | 5 +- contracts/interfaces/IBlockTracker.sol | 26 +- contracts/interfaces/IPreConfirmations.sol | 4 +- test/BidderRegistryTest.sol | 77 +++-- test/OracleTest.sol | 323 +++++++++++---------- test/PreConfirmationConfTest.sol | 34 ++- 11 files changed, 335 insertions(+), 312 deletions(-) diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index a7712dc..f6f27ca 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -48,7 +48,6 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { mapping(address => uint256) public providerAmount; /// @dev Event emitted when a bidder is registered with their prepayed amount - // event BidderRegistered(address indexed bidder, uint256 prepaidAmount); event BidderRegistered( address indexed bidder, uint256 prepaidAmount, @@ -56,7 +55,21 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { ); /// @dev Event emitted when funds are retrieved from a bidder's prepay - event FundsRetrieved(bytes32 indexed commitmentDigest, uint256 window, uint256 amount); + event FundsRetrieved( + bytes32 indexed commitmentDigest, + address indexed bidder, + uint256 window, + uint256 amount + ); + + /// @dev Event emitted when funds are retrieved from a bidder's prepay + event FundsRewarded( + bytes32 indexed commitmentDigest, + address indexed bidder, + address indexed provider, + uint256 window, + uint256 amount + ); /// @dev Event emitted when a bidder withdraws their prepay event BidderWithdrawal( @@ -77,7 +90,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * Should be removed from here in case the prepay function becomes more complex */ receive() external payable { - prepay(); + revert("Invalid call"); } /** @@ -142,27 +155,6 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { return feeRecipientAmount; } - /** - * @dev Internal function for bidder registration and staking. - */ - function prepay() public payable { - require(msg.value >= minAllowance, "Insufficient prepay"); - - bidderRegistered[msg.sender] = true; - - uint256 currentWindow = blockTrackerContract.getCurrentWindow(); - uint256 nextWindow = currentWindow + 1; - - // Lock the funds for the next window - lockedFunds[msg.sender][nextWindow] += msg.value; - - emit BidderRegistered( - msg.sender, - lockedFunds[msg.sender][nextWindow], - nextWindow - ); - } - /** * @dev Prepay for a specific window. * @param window The window for which the prepay is being made. @@ -229,7 +221,13 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { BidPayment[commitmentDigest].state = State.Withdrawn; BidPayment[commitmentDigest].bidAmt = 0; - emit FundsRetrieved(commitmentDigest, windowToSettle, decayedAmt); + emit FundsRewarded( + commitmentDigest, + bidState.bidder, + provider, + windowToSettle, + decayedAmt + ); } /** @@ -246,7 +244,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { BidPayment[bidID].state = State.Withdrawn; BidPayment[bidID].bidAmt = 0; - emit FundsRetrieved(bidID, window, amt); + emit FundsRetrieved(bidID, bidState.bidder, window, amt); } /** @@ -258,11 +256,12 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { function OpenBid( bytes32 commitmentDigest, uint64 bid, - address bidder + address bidder, + uint64 blockNumber ) external onlyPreConfirmationEngine { BidState memory bidState = BidPayment[commitmentDigest]; if (bidState.state == State.Undefined) { - uint256 currentWindow = blockTrackerContract.getCurrentWindow(); + uint256 currentWindow = blockTrackerContract.getWindowFromBlockNumber(blockNumber); // @todo delete this, when oracle will do the calculation // bidder cannot bid more than allowed for the round uint256 numberOfRounds = blockTrackerContract.getBlocksPerWindow(); diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol index eef35b6..d65efe3 100644 --- a/contracts/BlockTracker.sol +++ b/contracts/BlockTracker.sol @@ -22,12 +22,13 @@ contract BlockTracker is Ownable { uint256 public currentWindow = 1; uint256 public blocksPerWindow = 64; - uint256 public lastL1BlockNumber; - address public lastL1BlockWinner; // Mapping from block number to the winner's address mapping(uint256 => address) public blockWinners; + /// @dev Maps builder names to their respective Ethereum addresses. + mapping(string => address) public blockBuilderNameToAddress; + /** * @dev Initializes the BlockTracker contract with the specified owner. * @param _owner The address of the contract owner. @@ -37,19 +38,42 @@ contract BlockTracker is Ownable { } /** - * @dev Returns the number of the last L1 block recorded. - * @return The number of the last L1 block recorded. + * @dev Retrieves the current window number. + * @return The current window number. + */ + function getCurrentWindow() external view returns (uint256) { + return currentWindow; + } + + /** + * @dev Allows the owner to add a new builder address. + * @param builderName The name of the block builder as it appears on extra data. + * @param builderAddress The Ethereum address of the builder. + */ + function addBuilderAddress( + string memory builderName, + address builderAddress + ) external onlyOwner { + blockBuilderNameToAddress[builderName] = builderAddress; + } + + /** + * @dev Returns the builder's address corresponding to the given name. + * @param builderNameGrafiti The name (or graffiti) of the block builder. */ - function getLastL1BlockNumber() external view returns (uint256) { - return lastL1BlockNumber; + function getBuilder( + string calldata builderNameGrafiti + ) external view returns (address) { + return blockBuilderNameToAddress[builderNameGrafiti]; } /** - * @dev Returns the winner of the last L1 block recorded. - * @return The address of the winner of the last L1 block recorded. + * @dev Returns the window number corresponding to a given block number. + * @param blockNumber The block number. + * @return The window number. */ - function getLastL1BlockWinner() external view returns (address) { - return lastL1BlockWinner; + function getWindowFromBlock(uint256 blockNumber) external view returns (uint256) { + return (blockNumber - 1) / blocksPerWindow + 1; } /** @@ -69,25 +93,17 @@ contract BlockTracker is Ownable { emit NewBlocksPerWindow(blocksPerWindow); } - /** - * @dev Returns the current window number. - * @return The current window number. - */ - function getCurrentWindow() external view returns (uint256) { - return currentWindow; - } /** * @dev Records a new L1 block and its winner. * @param _blockNumber The number of the new L1 block. - * @param _winner The address of the winner of the new L1 block. + * @param _winnerGraffiti The graffiti of the winner of the new L1 block. */ function recordL1Block( uint256 _blockNumber, - address _winner + string calldata _winnerGraffiti ) external onlyOwner { - lastL1BlockNumber = _blockNumber; - lastL1BlockWinner = _winner; + address _winner = blockBuilderNameToAddress[_winnerGraffiti]; recordBlockWinner(_blockNumber, _winner); uint256 newWindow = (_blockNumber - 1) / blocksPerWindow + 1; if (newWindow > currentWindow) { diff --git a/contracts/Oracle.sol b/contracts/Oracle.sol index 6f03c74..825e2b7 100644 --- a/contracts/Oracle.sol +++ b/contracts/Oracle.sol @@ -57,45 +57,26 @@ contract Oracle is Ownable { /// @dev Event emitted when a commitment is processed. event CommitmentProcessed(bytes32 commitmentHash, bool isSlash); - /** - * @dev Allows the owner to add a new builder address. - * @param builderName The name of the block builder as it appears on extra data. - * @param builderAddress The Ethereum address of the builder. - */ - function addBuilderAddress( - string memory builderName, - address builderAddress - ) external onlyOwner { - blockBuilderNameToAddress[builderName] = builderAddress; - } - - /** - * @dev Returns the builder's address corresponding to the given name. - * @param builderNameGrafiti The name (or graffiti) of the block builder. - */ - function getBuilder( - string calldata builderNameGrafiti - ) external view returns (address) { - return blockBuilderNameToAddress[builderNameGrafiti]; - } - // Function to receive and process the block data (this would be automated in a real-world scenario) /** * @dev Processes a builder's commitment for a specific block number. * @param commitmentIndex The id of the commitment in the PreConfCommitmentStore. * @param blockNumber The block number to be processed. - * @param blockBuilderName The name of the block builder. + * @param builder The address of the builder. * @param isSlash Determines whether the commitment should be slashed or rewarded. */ function processBuilderCommitmentForBlockNumber( bytes32 commitmentIndex, uint256 blockNumber, - string calldata blockBuilderName, + address builder, bool isSlash, uint256 residualBidPercentAfterDecay ) external onlyOwner { - // Check graffiti against registered builder IDs - address builder = blockBuilderNameToAddress[blockBuilderName]; + address winner = blockTrackerContract.getBlockWinner(blockNumber); + require( + winner == builder, + "Builder is not the winner of the block" + ); require( residualBidPercentAfterDecay <= 100, "Residual bid after decay cannot be greater than 100 percent" @@ -114,16 +95,6 @@ contract Oracle is Ownable { } } - /** - * @dev unlocks funds to the bidders assosciated with BidIDs in the input array. - * @param bidIDs The array of BidIDs to unlock funds for. - */ - function unlockFunds(uint256 window, bytes32[] memory bidIDs) external onlyOwner { - for (uint256 i = 0; i < bidIDs.length; i++) { - preConfContract.unlockBidFunds(window, bidIDs[i]); - } - } - /** * @dev Internal function to process a commitment, either slashing or rewarding based on the commitment's state. * @param commitmentIndex The id of the commitment to be processed. @@ -134,17 +105,13 @@ contract Oracle is Ownable { bool isSlash, uint256 residualBidPercentAfterDecay ) private { - // processing commitment after window has been settled - uint256 windowToSettle = blockTrackerContract.getCurrentWindow() - 1; if (isSlash) { preConfContract.initiateSlash( - windowToSettle, commitmentIndex, residualBidPercentAfterDecay ); } else { preConfContract.initiateReward( - windowToSettle, commitmentIndex, residualBidPercentAfterDecay ); diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 48a7e41..1abaecb 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -455,7 +455,7 @@ contract PreConfCommitmentStore is Ownable { providerCommitments[commiterAddress].push(commitmentIndex); blockCommitments[blockNumber].push(commitmentIndex); - bidderRegistry.OpenBid(commitmentDigest, bid, bidderAddress); + bidderRegistry.OpenBid(commitmentDigest, bid, bidderAddress, blockNumber); emit CommitmentStored( commitmentIndex, @@ -584,7 +584,6 @@ contract PreConfCommitmentStore is Ownable { * @param commitmentIndex The hash of the commitment to be slashed. */ function initiateSlash( - uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualBidPercentAfterDecay ) public onlyOracle { @@ -594,6 +593,8 @@ contract PreConfCommitmentStore is Ownable { "Commitment already used" ); + uint256 windowToSettle = blockTracker.getWindowFromBlockNumber(commitment.blockNumber); + // Mark this commitment as used to prevent replays commitments[commitmentIndex].commitmentUsed = true; commitmentsCount[commitment.commiter] -= 1; @@ -608,20 +609,11 @@ contract PreConfCommitmentStore is Ownable { bidderRegistry.unlockFunds(windowToSettle, commitment.commitmentHash); } - /** - * @dev Initiate a return of funds for a bid that was not slashed. - * @param commitmentDigest The hash of the bid to be unlocked. - */ - function unlockBidFunds(uint256 windowToSettle,bytes32 commitmentDigest) public onlyOracle { - bidderRegistry.unlockFunds(windowToSettle, commitmentDigest); - } - /** * @dev Initiate a reward for a commitment. * @param commitmentIndex The hash of the commitment to be rewarded. */ function initiateReward( - uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualBidPercentAfterDecay ) public onlyOracle { @@ -631,6 +623,8 @@ contract PreConfCommitmentStore is Ownable { "Commitment already used" ); + uint256 windowToSettle = blockTracker.getWindowFromBlockNumber(commitment.blockNumber); + // Mark this commitment as used to prevent replays commitments[commitmentIndex].commitmentUsed = true; commitmentsCount[commitment.commiter] -= 1; diff --git a/contracts/ProviderRegistry.sol b/contracts/ProviderRegistry.sol index baafe2a..f04547f 100644 --- a/contracts/ProviderRegistry.sol +++ b/contracts/ProviderRegistry.sol @@ -47,8 +47,6 @@ contract ProviderRegistry is IProviderRegistry, Ownable, ReentrancyGuard { /// @dev Event for slashing funds event FundsSlashed(address indexed provider, uint256 amount); - /// @dev Event for rewarding funds - event FundsRewarded(address indexed provider, uint256 amount); /** * @dev Fallback function to revert all calls, ensuring no unintended interactions. diff --git a/contracts/interfaces/IBidderRegistry.sol b/contracts/interfaces/IBidderRegistry.sol index cabc7f8..ddf9a18 100644 --- a/contracts/interfaces/IBidderRegistry.sol +++ b/contracts/interfaces/IBidderRegistry.sol @@ -25,12 +25,13 @@ interface IBidderRegistry { Withdrawn } - function prepay() external payable; - function OpenBid(bytes32 commitmentDigest, uint64 bid, address bidder) external; + function OpenBid(bytes32 commitmentDigest, uint64 bid, address bidder, uint64 blockNumber) external; function getAllowance(address bidder, uint256 window) external view returns (uint256); + function prepayAllowanceForSpecificWindow(uint256 window) external payable; + function retrieveFunds( uint256 windowToSettle, bytes32 commitmentDigest, diff --git a/contracts/interfaces/IBlockTracker.sol b/contracts/interfaces/IBlockTracker.sol index dadab1f..5ba780f 100644 --- a/contracts/interfaces/IBlockTracker.sol +++ b/contracts/interfaces/IBlockTracker.sol @@ -3,18 +3,20 @@ pragma solidity ^0.8.20; /// @title IBlockTracker interface for BlockTracker contract interface IBlockTracker { - /// @notice Retrieves the number of the last L1 block tracked. - /// @return The block number of the last tracked L1 block. - function getLastL1BlockNumber() external view returns (uint256); + /// @notice Retrieves the builder's address corresponding to the given name. + /// @param builderNameGrafiti The name of the block builder. + /// @return The Ethereum address of the builder. + function getBuilder(string calldata builderNameGrafiti) external view returns (address); - /// @notice Retrieves the winner of the last L1 block tracked. - /// @return The address of the winner of the last tracked L1 block. - function getLastL1BlockWinner() external view returns (address); - - /// @notice Retrieves the current window. + /// @notice Gets the current window number. /// @return The current window number. function getCurrentWindow() external view returns (uint256); + /// @notice Gets the window number for a given block number. + /// @param blockNumber The block number. + /// @return The window number. + function getWindowFromBlockNumber(uint256 blockNumber) external view returns (uint256); + /// @notice Retrieves the number of blocks per window. /// @return The number of blocks per window. function getBlocksPerWindow() external view returns (uint256); @@ -31,8 +33,8 @@ interface IBlockTracker { /// @notice Records a new L1 block with its winner. /// @param _blockNumber The block number of the new L1 block. - /// @param _winner The address of the winner of the new L1 block. - function recordL1Block(uint256 _blockNumber, address _winner) external; + /// @param _winnerGrafitti The graffiti of the winner of the new L1 block. + function recordL1Block(uint256 _blockNumber, string calldata _winnerGrafitti) external; /// @notice Emitted when a new L1 block is recorded. /// @param blockNumber The block number of the new L1 block. @@ -42,4 +44,8 @@ interface IBlockTracker { /// @notice Emitted when entering a new window. /// @param window The new window number. event NewWindow(uint256 indexed window); + + /// @notice Emitted when the number of blocks per window is updated. + /// @param blocksPerWindow The new number of blocks per window. + event NewBlocksPerWindow(uint256 blocksPerWindow); } diff --git a/contracts/interfaces/IPreConfirmations.sol b/contracts/interfaces/IPreConfirmations.sol index c9e64a8..ca89fe8 100644 --- a/contracts/interfaces/IPreConfirmations.sol +++ b/contracts/interfaces/IPreConfirmations.sol @@ -90,9 +90,9 @@ interface IPreConfCommitmentStore { function getEncryptedCommitment(bytes32 commitmentIndex) external view returns (EncrPreConfCommitment memory); - function initiateSlash(uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualDecayedBid) external; + function initiateSlash(bytes32 commitmentIndex, uint256 residualDecayedBid) external; - function initiateReward(uint256 windowToSettle, bytes32 commitmentIndex, uint256 residualDecayedBid) external; + function initiateReward(bytes32 commitmentIndex, uint256 residualDecayedBid) external; function unlockBidFunds(uint256 windowToSettle, bytes32 commitmentDigest) external; diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index dc78dce..1860ca0 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -41,7 +41,7 @@ contract BidderRegistryTest is Test { function testFail_BidderStakeAndRegisterMinStake() public { vm.prank(bidder); vm.expectRevert(bytes("")); - bidderRegistry.prepay{value: 1 wei}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 wei}(2); } function test_BidderStakeAndRegister() public { @@ -53,7 +53,7 @@ contract BidderRegistryTest is Test { emit BidderRegistered(bidder, 1 ether, nextWindow); - bidderRegistry.prepay{value: 1 ether}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 ether}(nextWindow); bool isBidderRegistered = bidderRegistry.bidderRegistered(bidder); assertEq(isBidderRegistered, true); @@ -69,7 +69,7 @@ contract BidderRegistryTest is Test { emit BidderRegistered(bidder, 2 ether, nextWindow); - bidderRegistry.prepay{value: 1 ether}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 ether}(nextWindow); uint256 bidderStakeStored2 = bidderRegistry.getAllowance(bidder, nextWindow); assertEq(bidderStakeStored2, 2 ether); @@ -78,9 +78,9 @@ contract BidderRegistryTest is Test { function testFail_BidderStakeAndRegisterAlreadyRegistered() public { vm.prank(bidder); - bidderRegistry.prepay{value: 2e18 wei}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2e18 wei}(2); vm.expectRevert(bytes("")); - bidderRegistry.prepay{value: 1 wei}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 wei}(2); } function testFail_receive() public { @@ -144,12 +144,13 @@ contract BidderRegistryTest is Test { uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepay{value: 64 ether}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 64 ether}(nextWindow); address provider = vm.addr(4); - uint256 blockNumber = 66; - blockTracker.recordL1Block(blockNumber, provider); + uint64 blockNumber = 66; + blockTracker.addBuilderAddress("test", provider); + blockTracker.recordL1Block(blockNumber, "test"); - bidderRegistry.OpenBid(bidID, 1 ether, bidder); + bidderRegistry.OpenBid(bidID, 1 ether, bidder, blockNumber); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); uint256 providerAmount = bidderRegistry.providerAmount(provider); @@ -172,13 +173,14 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepay{value: 64 ether}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 64 ether}(nextWindow); address provider = vm.addr(4); - uint256 blockNumber = 66; - blockTracker.recordL1Block(blockNumber, provider); + uint64 blockNumber = 66; + blockTracker.addBuilderAddress("test", provider); + blockTracker.recordL1Block(blockNumber, "test"); bytes32 bidID = keccak256("1234"); - bidderRegistry.OpenBid(bidID, 1 ether, bidder); + bidderRegistry.OpenBid(bidID, 1 ether, bidder, blockNumber); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); uint256 feerecipientValueAfter = bidderRegistry.feeRecipientAmount(); @@ -194,11 +196,12 @@ contract BidderRegistryTest is Test { vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; - bidderRegistry.prepay{value: 2 ether}(); + uint64 blockNumber = 66; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(nextWindow); address provider = vm.addr(4); vm.expectRevert(bytes("")); bytes32 bidID = keccak256("1234"); - bidderRegistry.OpenBid(bidID, 1 ether, bidder); + bidderRegistry.OpenBid(bidID, 1 ether, bidder, blockNumber); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); } @@ -209,29 +212,31 @@ contract BidderRegistryTest is Test { vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; - bidderRegistry.prepay{value: 2 ether}(); + uint64 blockNumber = 66; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(nextWindow); address provider = vm.addr(4); vm.expectRevert(bytes("")); vm.prank(address(this)); bytes32 bidID = keccak256("1234"); - bidderRegistry.OpenBid(bidID, 3 ether, bidder); + bidderRegistry.OpenBid(bidID, 3 ether, bidder, blockNumber); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); } function test_withdrawFeeRecipientAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); - bidderRegistry.prepay{value: 64 ether}(); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 64 ether}(nextWindow); address provider = vm.addr(4); uint256 balanceBefore = feeRecipient.balance; bytes32 bidID = keccak256("1234"); - uint256 blockNumber = 66; - blockTracker.recordL1Block(blockNumber, provider); + uint64 blockNumber = 66; + blockTracker.addBuilderAddress("test", provider); + blockTracker.recordL1Block(blockNumber, "test"); - bidderRegistry.OpenBid(bidID, 1 ether, bidder); + bidderRegistry.OpenBid(bidID, 1 ether, bidder, blockNumber); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider),100); bidderRegistry.withdrawFeeRecipientAmount(); uint256 balanceAfter = feeRecipient.balance; @@ -248,16 +253,17 @@ contract BidderRegistryTest is Test { function test_withdrawProviderAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); - bidderRegistry.prepay{value: 128 ether}(); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 128 ether}(nextWindow); address provider = vm.addr(4); uint256 balanceBefore = address(provider).balance; bytes32 bidID = keccak256("1234"); - uint256 blockNumber = 66; - blockTracker.recordL1Block(blockNumber, provider); + uint64 blockNumber = 66; + blockTracker.addBuilderAddress("test", provider); + blockTracker.recordL1Block(blockNumber, "test"); - bidderRegistry.OpenBid(bidID, 2 ether, bidder); + bidderRegistry.OpenBid(bidID, 2 ether, bidder, blockNumber); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); bidderRegistry.withdrawProviderAmount(payable(provider)); @@ -269,7 +275,9 @@ contract BidderRegistryTest is Test { function testFail_withdrawProviderAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); vm.prank(bidder); - bidderRegistry.prepay{value: 5 ether}(); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 5 ether}(nextWindow); address provider = vm.addr(4); bidderRegistry.withdrawProviderAmount(payable(provider)); } @@ -279,15 +287,16 @@ contract BidderRegistryTest is Test { bidderRegistry.setPreconfirmationsContract(address(this)); bidderRegistry.setNewFeeRecipient(address(0)); vm.prank(bidder); - bidderRegistry.prepay{value: 128 ether}(); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 128 ether}(nextWindow); uint256 balanceBefore = address(bidder).balance; bytes32 bidID = keccak256("1234"); - uint256 blockNumber = 66; - blockTracker.recordL1Block(blockNumber, provider); + uint64 blockNumber = 66; + blockTracker.addBuilderAddress("test", provider); + blockTracker.recordL1Block(blockNumber, "test"); - bidderRegistry.OpenBid(bidID, 2 ether, bidder); + bidderRegistry.OpenBid(bidID, 2 ether, bidder, blockNumber); bidderRegistry.retrieveFunds(nextWindow, bidID, payable(provider), 100); vm.prank(bidderRegistry.owner()); bidderRegistry.withdrawProtocolFee(payable(address(bidder))); @@ -300,7 +309,9 @@ contract BidderRegistryTest is Test { bidderRegistry.setPreconfirmationsContract(address(this)); bidderRegistry.setNewFeeRecipient(address(0)); vm.prank(bidder); - bidderRegistry.prepay{value: 5 ether}(); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 5 ether}(nextWindow); vm.prank(bidderRegistry.owner()); bidderRegistry.withdrawProtocolFee(payable(address(bidder))); } @@ -309,7 +320,9 @@ contract BidderRegistryTest is Test { bidderRegistry.setPreconfirmationsContract(address(this)); bidderRegistry.setNewFeeRecipient(address(0)); vm.prank(bidder); - bidderRegistry.prepay{value: 5 ether}(); + uint256 currentWindow = blockTracker.getCurrentWindow(); + uint256 nextWindow = currentWindow + 1; + bidderRegistry.prepayAllowanceForSpecificWindow{value: 5 ether}(nextWindow); bidderRegistry.withdrawProtocolFee(payable(address(bidder))); } } diff --git a/test/OracleTest.sol b/test/OracleTest.sol index 3461851..9021d7a 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -82,10 +82,10 @@ contract OracleTest is Test { vm.deal(ownerInstance, 5 ether); vm.startPrank(ownerInstance); - bidderRegistry.prepay{value: 2 ether}(); + uint256 window = blockTracker.getCurrentWindow(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(window+1); oracle = new Oracle(address(preConfCommitmentStore), address(blockTracker), ownerInstance); - oracle.addBuilderAddress("mev builder", ownerInstance); vm.stopPrank(); preConfCommitmentStore.updateOracle(address(oracle)); @@ -94,83 +94,83 @@ contract OracleTest is Test { } - function test_MultipleBlockBuildersRegistred() public { - vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); - (address builder1,) = makeAddrAndKey("k builder"); - (address builder2,) = makeAddrAndKey("primev builder"); - (address builder3,) = makeAddrAndKey("titan builder"); - (address builder4,) = makeAddrAndKey("zk builder"); - - - oracle.addBuilderAddress("k builder", builder1); - oracle.addBuilderAddress("primev builder", builder2); - oracle.addBuilderAddress("titan builder", builder3); - oracle.addBuilderAddress("zk builder", builder4); - - assertEq(oracle.blockBuilderNameToAddress("k builder"), builder1); - assertEq(oracle.blockBuilderNameToAddress("primev builder"), builder2); - assertEq(oracle.blockBuilderNameToAddress("titan builder"), builder3); - assertEq(oracle.blockBuilderNameToAddress("zk builder"), builder4); - } - - function test_builderUnidentified() public { - vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); - // Unregistered Builder - (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); - (address provider, uint256 providerPk) = makeAddrAndKey("bob"); - - (address builder3,) = makeAddrAndKey("titan builder"); - (address builder4,) = makeAddrAndKey("zk builder"); - - oracle.addBuilderAddress("titan builder", builder3); - oracle.addBuilderAddress("zk builder", builder4); - - assertEq(oracle.blockBuilderNameToAddress("titan builder"), builder3); - assertEq(oracle.blockBuilderNameToAddress("zk builder"), builder4); - vm.stopPrank(); - - vm.deal(bidder, 1000 ether); - vm.deal(provider, 1000 ether); - - vm.startPrank(bidder); - bidderRegistry.prepay{value: 250 ether }(); - vm.stopPrank(); - - vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(); - vm.stopPrank(); - - bytes32 commitmentIndex = constructAndStoreCommitment( - _testCommitmentAliceBob.bid, - _testCommitmentAliceBob.blockNumber, - _testCommitmentAliceBob.txnHash, - _testCommitmentAliceBob.decayStartTimestamp, - _testCommitmentAliceBob.decayEndTimestamp, - bidderPk, - providerPk, - provider - ); - - string[] memory txnList = new string[](1); - txnList[0] = string(abi.encodePacked(keccak256("0xkartik"))); - vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); - oracle.processBuilderCommitmentForBlockNumber(commitmentIndex, _testCommitmentAliceBob.blockNumber, "k builder", false, 50); - vm.stopPrank(); - assertEq(bidderRegistry.getProviderAmount(provider), 0); - assertEq(providerRegistry.checkStake(provider), 250 ether); - } + // function test_MultipleBlockBuildersRegistred() public { + // vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); + // (address builder1,) = makeAddrAndKey("k builder"); + // (address builder2,) = makeAddrAndKey("primev builder"); + // (address builder3,) = makeAddrAndKey("titan builder"); + // (address builder4,) = makeAddrAndKey("zk builder"); + + + // oracle.addBuilderAddress("k builder", builder1); + // oracle.addBuilderAddress("primev builder", builder2); + // oracle.addBuilderAddress("titan builder", builder3); + // oracle.addBuilderAddress("zk builder", builder4); + + // assertEq(oracle.blockBuilderNameToAddress("k builder"), builder1); + // assertEq(oracle.blockBuilderNameToAddress("primev builder"), builder2); + // assertEq(oracle.blockBuilderNameToAddress("titan builder"), builder3); + // assertEq(oracle.blockBuilderNameToAddress("zk builder"), builder4); + // } + + // function test_builderUnidentified() public { + // vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); + // // Unregistered Builder + // (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); + // (address provider, uint256 providerPk) = makeAddrAndKey("bob"); + + // (address builder3,) = makeAddrAndKey("titan builder"); + // (address builder4,) = makeAddrAndKey("zk builder"); + + // oracle.addBuilderAddress("titan builder", builder3); + // oracle.addBuilderAddress("zk builder", builder4); + + // assertEq(oracle.blockBuilderNameToAddress("titan builder"), builder3); + // assertEq(oracle.blockBuilderNameToAddress("zk builder"), builder4); + // vm.stopPrank(); + + // vm.deal(bidder, 1000 ether); + // vm.deal(provider, 1000 ether); + + // vm.startPrank(bidder); + // bidderRegistry.prepay{value: 250 ether }(); + // vm.stopPrank(); + + // vm.startPrank(provider); + // providerRegistry.registerAndStake{value: 250 ether}(); + // vm.stopPrank(); + + // bytes32 commitmentIndex = constructAndStoreCommitment( + // _testCommitmentAliceBob.bid, + // _testCommitmentAliceBob.blockNumber, + // _testCommitmentAliceBob.txnHash, + // _testCommitmentAliceBob.decayStartTimestamp, + // _testCommitmentAliceBob.decayEndTimestamp, + // bidderPk, + // providerPk, + // provider + // ); + + // string[] memory txnList = new string[](1); + // txnList[0] = string(abi.encodePacked(keccak256("0xkartik"))); + // vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); + // oracle.processBuilderCommitmentForBlockNumber(commitmentIndex, _testCommitmentAliceBob.blockNumber, "k builder", false, 50); + // vm.stopPrank(); + // assertEq(bidderRegistry.getProviderAmount(provider), 0); + // assertEq(providerRegistry.checkStake(provider), 250 ether); + // } function test_process_commitment_payment_payout() public { string memory txn = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; uint64 blockNumber = 66; uint64 bid = 2; - string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); vm.deal(bidder, 200000 ether); vm.startPrank(bidder); - bidderRegistry.prepay{value: 250 ether }(); + uint256 window = blockTracker.getCurrentWindow(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -181,9 +181,8 @@ contract OracleTest is Test { bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk, provider); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); - oracle.addBuilderAddress(blockBuilderName, provider); - oracle.processBuilderCommitmentForBlockNumber(index, blockNumber, blockBuilderName, false, 50); + oracle.processBuilderCommitmentForBlockNumber(index, blockNumber, provider, false, 50); vm.stopPrank(); assertEq(bidderRegistry.getProviderAmount(provider), bid*(50)/100); @@ -194,13 +193,13 @@ contract OracleTest is Test { string memory txn = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; uint64 blockNumber = 200; uint64 bid = 200; - string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); vm.deal(bidder, 200000 ether); vm.startPrank(bidder); - bidderRegistry.prepay{value: 250 ether }(); + uint256 window = blockTracker.getCurrentWindow(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -211,11 +210,10 @@ contract OracleTest is Test { bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk, provider); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); - oracle.addBuilderAddress(blockBuilderName, provider); vm.expectEmit(true, false, false, true); emit CommitmentProcessed(index, true); - oracle.processBuilderCommitmentForBlockNumber(index, blockNumber, blockBuilderName, true,50); + oracle.processBuilderCommitmentForBlockNumber(index, blockNumber, provider, true,50); vm.stopPrank(); assertEq(providerRegistry.checkStake(provider) + ((bid * 50)/100), 250 ether); } @@ -226,7 +224,6 @@ contract OracleTest is Test { string memory txn2 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d09"; uint64 blockNumber = 66; uint64 bid = 100; - string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); @@ -234,7 +231,8 @@ contract OracleTest is Test { vm.deal(bidder, 200000 ether); vm.startPrank(bidder); - bidderRegistry.prepay{value: 250 ether }(); + uint256 window = blockTracker.getCurrentWindow(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -246,15 +244,14 @@ contract OracleTest is Test { bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk, provider); vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); - oracle.addBuilderAddress(blockBuilderName, provider); vm.expectEmit(true, false, false, true); emit CommitmentProcessed(index1, true); - oracle.processBuilderCommitmentForBlockNumber(index1, blockNumber, blockBuilderName, true,100); + oracle.processBuilderCommitmentForBlockNumber(index1, blockNumber, provider, true,100); vm.expectEmit(true, false, false, true); emit CommitmentProcessed(index2, false); - oracle.processBuilderCommitmentForBlockNumber(index2, blockNumber, blockBuilderName, false,50); + oracle.processBuilderCommitmentForBlockNumber(index2, blockNumber, provider, false,50); vm.stopPrank(); assertEq(providerRegistry.checkStake(provider), 250 ether - bid); assertEq(bidderRegistry.getProviderAmount(provider), (bid * (100 - feePercent) /100) * residualAfterDecay /100 ); @@ -268,13 +265,13 @@ contract OracleTest is Test { string memory txn4 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d11"; uint64 blockNumber = 201; uint64 bid = 5; - string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); vm.deal(bidder, 200000 ether); vm.startPrank(bidder); - bidderRegistry.prepay{value: 250 ether }(); + uint256 window = blockTracker.getWindowFromBlock(blockNumber); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -289,39 +286,39 @@ contract OracleTest is Test { vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); - oracle.addBuilderAddress(blockBuilderName, provider); vm.expectEmit(true, false, false, true); emit CommitmentProcessed(index1, true); - oracle.processBuilderCommitmentForBlockNumber(index1, blockNumber, blockBuilderName, true,100); + oracle.processBuilderCommitmentForBlockNumber(index1, blockNumber, provider, true,100); vm.expectEmit(true, false, false, true); emit CommitmentProcessed(index2, true); - oracle.processBuilderCommitmentForBlockNumber(index2, blockNumber, blockBuilderName, true,100); + oracle.processBuilderCommitmentForBlockNumber(index2, blockNumber, provider, true,100); vm.expectEmit(true, false, false, true); emit CommitmentProcessed(index3, true); - oracle.processBuilderCommitmentForBlockNumber(index3, blockNumber, blockBuilderName, true,100); + oracle.processBuilderCommitmentForBlockNumber(index3, blockNumber, provider, true,100); vm.expectEmit(true, false, false, true); emit CommitmentProcessed(index4, true); - oracle.processBuilderCommitmentForBlockNumber(index4, blockNumber, blockBuilderName, true,100); + oracle.processBuilderCommitmentForBlockNumber(index4, blockNumber, provider, true,100); vm.stopPrank(); assertEq(providerRegistry.checkStake(provider), 250 ether - bid*4); assertEq(bidderRegistry.getProviderAmount(provider), 0); } function test_process_commitment_reward_multiple() public { - string memory txn1 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; - string memory txn2 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d09"; - string memory txn3 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d10"; - string memory txn4 = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d11"; + string[] memory txnHashes = new string[](4); + txnHashes[0] = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; + txnHashes[1] = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d09"; + txnHashes[2] = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d10"; + txnHashes[3] = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d11"; uint64 blockNumber = 66; uint64 bid = 5; - string memory blockBuilderName = "kartik builder"; (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); vm.deal(bidder, 200000 ether); vm.startPrank(bidder); - bidderRegistry.prepay{value: 250 ether }(); + uint256 window = blockTracker.getCurrentWindow(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -329,69 +326,51 @@ contract OracleTest is Test { providerRegistry.registerAndStake{value: 250 ether}(); vm.stopPrank(); - bytes32 index1 = constructAndStoreCommitment(bid, blockNumber, txn1, 10, 20, bidderPk, providerPk, provider); - // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - bid); - bytes32 index2 = constructAndStoreCommitment(bid, blockNumber, txn2, 10, 20, bidderPk, providerPk, provider); - // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 2*bid); - bytes32 index3 = constructAndStoreCommitment(bid, blockNumber, txn3, 10, 20, bidderPk, providerPk, provider); - // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 3*bid); - bytes32 index4 = constructAndStoreCommitment(bid, blockNumber, txn4, 10, 20, bidderPk, providerPk, provider); - // assertEq(bidderRegistry.bidderPrepaidBalances(bidder), 250 ether - 4*bid); + bytes32[] memory commitments = new bytes32[](4); + bytes[] memory bidSignatures = new bytes[](4); + bytes[] memory commitmentSignatures = new bytes[](4); + for (uint i = 0; i < commitments.length; i++) { + (commitments[i], bidSignatures[i], commitmentSignatures[i]) = constructAndStoreEncryptedCommitment( + bid, + blockNumber, + txnHashes[i], + 10, + 20, + bidderPk, + providerPk + ); + } + blockTracker.addBuilderAddress("test", provider); + blockTracker.recordL1Block(blockNumber, "test"); + + for (uint i = 0; i < commitments.length; i++) { + vm.startPrank(provider); + preConfCommitmentStore.openCommitment( + commitments[i], + bid, + blockNumber, + txnHashes[i], + 10, + 20, + bidSignatures[i], + commitmentSignatures[i], + sharedSecretKey + ); + vm.stopPrank(); + } + vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); - oracle.addBuilderAddress(blockBuilderName, provider); - - vm.expectEmit(true, false, false, true); - emit CommitmentProcessed(index1, false); - oracle.processBuilderCommitmentForBlockNumber(index1, blockNumber, blockBuilderName, false,100); - vm.expectEmit(true, false, false, true); - emit CommitmentProcessed(index2, false); - oracle.processBuilderCommitmentForBlockNumber(index2, blockNumber, blockBuilderName, false,100); - vm.expectEmit(true, false, false, true); - emit CommitmentProcessed(index3, false); - oracle.processBuilderCommitmentForBlockNumber(index3, blockNumber, blockBuilderName, false,100); - vm.expectEmit(true, false, false, true); - emit CommitmentProcessed(index4, false); - oracle.processBuilderCommitmentForBlockNumber(index4, blockNumber, blockBuilderName, false,100); + for (uint i = 0; i < commitments.length; i++) { + vm.expectEmit(true, false, false, true); + emit CommitmentProcessed(commitments[i], false); + oracle.processBuilderCommitmentForBlockNumber(commitments[i], blockNumber, provider, false,100); + } vm.stopPrank(); assertEq(providerRegistry.checkStake(provider), 250 ether); assertEq(bidderRegistry.getProviderAmount(provider), 4*bid); } - - function test_process_commitment_and_return() public { - string memory txn = "0x6d9c53ad81249775f8c082b11ac293b2e19194ff791bd1c4fd37683310e90d08"; - uint64 blockNumber = 66; - uint64 bid = 2; - (address bidder, uint256 bidderPk) = makeAddrAndKey("alice"); - (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); - - vm.deal(bidder, 200000 ether); - vm.startPrank(bidder); - bidderRegistry.prepay{value: 250 ether }(); - vm.stopPrank(); - - vm.deal(provider, 200000 ether); - vm.startPrank(provider); - providerRegistry.registerAndStake{value: 250 ether}(); - vm.stopPrank(); - - bytes32 index = constructAndStoreCommitment(bid, blockNumber, txn, 10, 20, bidderPk, providerPk, provider); - PreConfCommitmentStore.PreConfCommitment memory commitment = preConfCommitmentStore.getCommitment(index); - - vm.startPrank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3)); - bytes32[] memory commitments = new bytes32[](1); - commitments[0] = commitment.commitmentHash; - uint256 window = blockTracker.getCurrentWindow(); - vm.expectEmit(true, false, false, true); - emit FundsRetrieved(commitment.commitmentHash, window, bid); - oracle.unlockFunds(window, commitments); - - assertEq(providerRegistry.checkStake(provider) , 250 ether); - assertEq(bidderRegistry.lockedFunds(bidder, window), 250 ether); - } - - /** constructAndStoreCommitment is a helper function to construct and store a commitment */ @@ -436,7 +415,8 @@ contract OracleTest is Test { commitmentSignature ); vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); - blockTracker.recordL1Block(blockNumber, provider); + blockTracker.addBuilderAddress("test", provider); + blockTracker.recordL1Block(blockNumber, "test"); vm.stopPrank(); vm.startPrank(provider); commitmentIndex = preConfCommitmentStore.openCommitment( @@ -454,6 +434,49 @@ contract OracleTest is Test { return commitmentIndex; } + + function constructAndStoreEncryptedCommitment( + uint64 bid, + uint64 blockNumber, + string memory txnHash, + uint64 decayStartTimestamp, + uint64 decayEndTimestamp, + uint256 bidderPk, + uint256 signerPk + ) public returns (bytes32 commitmentIndex, bytes memory bidSignature, bytes memory commitmentSignature) { + bytes32 bidHash = preConfCommitmentStore.getBidHash( + txnHash, + bid, + blockNumber, + decayStartTimestamp, + decayEndTimestamp + ); + + + (uint8 v,bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash); + bidSignature = abi.encodePacked(r, s, v); + + bytes32 commitmentHash = preConfCommitmentStore.getPreConfHash( + txnHash, + bid, + blockNumber, + decayStartTimestamp, + decayEndTimestamp, + bidHash, + _bytesToHexString(bidSignature), + _bytesToHexString(sharedSecretKey) + ); + + (v,r,s) = vm.sign(signerPk, commitmentHash); + commitmentSignature = abi.encodePacked(r, s, v); + + bytes32 encryptedCommitmentIndex = preConfCommitmentStore.storeEncryptedCommitment( + commitmentHash, + commitmentSignature + ); + + return (encryptedCommitmentIndex, bidSignature, commitmentSignature); + } function _bytesToHexString( diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index ac78b8c..20686c1 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -209,7 +209,7 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(2); // Step 1: Verify that the commitment has not been used before verifyCommitmentNotUsed( @@ -234,7 +234,8 @@ contract TestPreConfCommitmentStore is Test { ); // Step 3: Move to the next window - blockTracker.recordL1Block(2, address(this)); + blockTracker.addBuilderAddress("test", address(this)); + blockTracker.recordL1Block(2, "test"); // Step 4: Open the commitment bytes32 index = openCommitment( @@ -431,7 +432,8 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + uint256 window = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(window); // Step 1: Verify that the commitment has not been used before verifyCommitmentNotUsed( _testCommitmentAliceBob.txnHash, @@ -472,7 +474,8 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + uint256 prepayWindow = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( @@ -517,7 +520,8 @@ contract TestPreConfCommitmentStore is Test { vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); uint256 blockNumber = 2; - blockTracker.recordL1Block(blockNumber, commiter); + blockTracker.addBuilderAddress("test", commiter); + blockTracker.recordL1Block(blockNumber, "test"); bytes32 index = openCommitment( commiter, encryptedIndex, @@ -530,9 +534,8 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.commitmentSignature, _testCommitmentAliceBob.sharedSecretKey ); - uint256 window = blockTracker.getCurrentWindow(); vm.prank(feeRecipient); - preConfCommitmentStore.initiateSlash(window, index, 100); + preConfCommitmentStore.initiateSlash(index, 100); (commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(index); @@ -548,7 +551,8 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + uint256 prepayWindow = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( @@ -588,7 +592,8 @@ contract TestPreConfCommitmentStore is Test { vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); - blockTracker.recordL1Block(_testCommitmentAliceBob.blockNumber, commiter); + blockTracker.addBuilderAddress("test", commiter); + blockTracker.recordL1Block(_testCommitmentAliceBob.blockNumber, "test"); bytes32 index = openCommitment( commiter, encryptedIndex, @@ -601,9 +606,8 @@ contract TestPreConfCommitmentStore is Test { _testCommitmentAliceBob.commitmentSignature, _testCommitmentAliceBob.sharedSecretKey ); - uint256 window = blockTracker.getCurrentWindow(); vm.prank(feeRecipient); - preConfCommitmentStore.initiateReward(window, index, 100); + preConfCommitmentStore.initiateReward(index, 100); (commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(index); @@ -619,7 +623,8 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - bidderRegistry.prepay{value: 2 ether}(); + uint256 prepayWindow = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); + bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( @@ -659,7 +664,8 @@ contract TestPreConfCommitmentStore is Test { vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); - blockTracker.recordL1Block(66, commiter); + blockTracker.addBuilderAddress("test", commiter); + blockTracker.recordL1Block(66, "test"); bytes32 index = openCommitment( commiter, encryptedIndex, @@ -674,7 +680,7 @@ contract TestPreConfCommitmentStore is Test { ); uint256 window = blockTracker.getCurrentWindow(); vm.prank(feeRecipient); - preConfCommitmentStore.initiateReward(window, index, 0); + preConfCommitmentStore.initiateReward(index, 0); (commitmentUsed, , , , , , , , , , , , , ) = preConfCommitmentStore .commitments(index); From ee8b1d51ba456543ed1b1b11c6aa0923172ac9c5 Mon Sep 17 00:00:00 2001 From: Alok Date: Fri, 19 Apr 2024 19:00:59 +0530 Subject: [PATCH 20/24] fix: tests --- contracts/BlockTracker.sol | 2 +- test/BidderRegistryTest.sol | 8 ++++---- test/OracleTest.sol | 6 ++++-- test/PreConfirmationConfTest.sol | 18 ++++++++++-------- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/contracts/BlockTracker.sol b/contracts/BlockTracker.sol index d65efe3..a39316a 100644 --- a/contracts/BlockTracker.sol +++ b/contracts/BlockTracker.sol @@ -72,7 +72,7 @@ contract BlockTracker is Ownable { * @param blockNumber The block number. * @return The window number. */ - function getWindowFromBlock(uint256 blockNumber) external view returns (uint256) { + function getWindowFromBlockNumber(uint256 blockNumber) external view returns (uint256) { return (blockNumber - 1) / blocksPerWindow + 1; } diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index 1860ca0..0c52f46 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -225,9 +225,9 @@ contract BidderRegistryTest is Test { function test_withdrawFeeRecipientAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); - vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; + vm.prank(bidder); bidderRegistry.prepayAllowanceForSpecificWindow{value: 64 ether}(nextWindow); address provider = vm.addr(4); uint256 balanceBefore = feeRecipient.balance; @@ -252,9 +252,9 @@ contract BidderRegistryTest is Test { function test_withdrawProviderAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); - vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; + vm.prank(bidder); bidderRegistry.prepayAllowanceForSpecificWindow{value: 128 ether}(nextWindow); address provider = vm.addr(4); uint256 balanceBefore = address(provider).balance; @@ -274,9 +274,9 @@ contract BidderRegistryTest is Test { function testFail_withdrawProviderAmount() public { bidderRegistry.setPreconfirmationsContract(address(this)); - vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; + vm.prank(bidder); bidderRegistry.prepayAllowanceForSpecificWindow{value: 5 ether}(nextWindow); address provider = vm.addr(4); bidderRegistry.withdrawProviderAmount(payable(provider)); @@ -286,9 +286,9 @@ contract BidderRegistryTest is Test { address provider = vm.addr(4); bidderRegistry.setPreconfirmationsContract(address(this)); bidderRegistry.setNewFeeRecipient(address(0)); - vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; + vm.prank(bidder); bidderRegistry.prepayAllowanceForSpecificWindow{value: 128 ether}(nextWindow); uint256 balanceBefore = address(bidder).balance; bytes32 bidID = keccak256("1234"); diff --git a/test/OracleTest.sol b/test/OracleTest.sol index 9021d7a..7f0fe97 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -269,8 +269,8 @@ contract OracleTest is Test { (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); vm.deal(bidder, 200000 ether); + uint256 window = blockTracker.getWindowFromBlockNumber(blockNumber); vm.startPrank(bidder); - uint256 window = blockTracker.getWindowFromBlock(blockNumber); bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window); vm.stopPrank(); @@ -316,8 +316,8 @@ contract OracleTest is Test { (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); vm.deal(bidder, 200000 ether); - vm.startPrank(bidder); uint256 window = blockTracker.getCurrentWindow(); + vm.startPrank(bidder); bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); @@ -341,8 +341,10 @@ contract OracleTest is Test { ); } + vm.startPrank(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3); blockTracker.addBuilderAddress("test", provider); blockTracker.recordL1Block(blockNumber, "test"); + vm.stopPrank(); for (uint i = 0; i < commitments.length; i++) { vm.startPrank(provider); diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index 20686c1..d0b4239 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -432,7 +432,8 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - uint256 window = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); + uint256 window = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); + vm.prank(bidder); bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(window); // Step 1: Verify that the commitment has not been used before verifyCommitmentNotUsed( @@ -474,7 +475,7 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - uint256 prepayWindow = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); + uint256 prepayWindow = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); // Step 1: Verify that the commitment has not been used before @@ -551,7 +552,7 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - uint256 prepayWindow = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); + uint256 prepayWindow = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); // Step 1: Verify that the commitment has not been used before @@ -621,9 +622,10 @@ contract TestPreConfCommitmentStore is Test { // Assuming you have a stored commitment { (address bidder, ) = makeAddrAndKey("alice"); + uint64 blockNumber = 66; + uint256 prepayWindow = blockTracker.getWindowFromBlockNumber(blockNumber); vm.deal(bidder, 5 ether); vm.prank(bidder); - uint256 prepayWindow = blockTracker.getWindowFromBlock(_testCommitmentAliceBob.blockNumber); bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); // Step 1: Verify that the commitment has not been used before @@ -652,7 +654,7 @@ contract TestPreConfCommitmentStore is Test { assert(commitmentUsed == false); bytes32 encryptedIndex = storeCommitment( _testCommitmentAliceBob.bid, - 66, + blockNumber, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, @@ -665,12 +667,12 @@ contract TestPreConfCommitmentStore is Test { vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); blockTracker.addBuilderAddress("test", commiter); - blockTracker.recordL1Block(66, "test"); + blockTracker.recordL1Block(blockNumber, "test"); bytes32 index = openCommitment( commiter, encryptedIndex, _testCommitmentAliceBob.bid, - 66, + blockNumber, _testCommitmentAliceBob.txnHash, _testCommitmentAliceBob.decayStartTimestamp, _testCommitmentAliceBob.decayEndTimestamp, @@ -704,4 +706,4 @@ contract TestPreConfCommitmentStore is Test { } return string(_string); } -} +} \ No newline at end of file From 1e5456680f7c1f0deb8aa1f275f9585b7e677d6c Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 22 Apr 2024 15:53:45 +0200 Subject: [PATCH 21/24] fixed block number for commitment opening --- contracts/PreConfirmations.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 1abaecb..9224f58 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -439,7 +439,7 @@ contract PreConfCommitmentStore is Ownable { commitmentDigest, bidSignature, commitmentSignature, - block.number, + encryptedCommitment.blockCommitedAt, sharedSecretKey ); From 8511899de441a54affaf3025e56fedaace3afc8e Mon Sep 17 00:00:00 2001 From: Mikelle Date: Mon, 22 Apr 2024 16:24:32 +0200 Subject: [PATCH 22/24] fixed CommitmentStored --- contracts/PreConfirmations.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 9224f58..b4f7621 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -470,7 +470,7 @@ contract PreConfCommitmentStore is Ownable { commitmentDigest, bidSignature, commitmentSignature, - block.number, + encryptedCommitment.blockCommitedAt, sharedSecretKey ); } From 401887412f7c372511bf760103ab0d5d59133128 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Tue, 23 Apr 2024 19:03:24 +0200 Subject: [PATCH 23/24] prepay -> allowance --- contracts/BidderRegistry.sol | 48 ++++++++++++------------ contracts/interfaces/IBidderRegistry.sol | 2 +- test/BidderRegistryTest.sol | 32 ++++++++-------- test/OracleTest.sol | 12 +++--- test/PreConfirmationConfTest.sol | 16 ++++---- 5 files changed, 55 insertions(+), 55 deletions(-) diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index f6f27ca..6eb8044 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -17,7 +17,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /// @dev Fee percent that would be taken by protocol when provider is slashed uint16 public feePercent; - /// @dev Minimum prepay required for registration + /// @dev Minimum deposit required for registration uint256 public minAllowance; /// @dev Amount assigned to feeRecipient @@ -47,14 +47,14 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /// @dev Amount assigned to bidders mapping(address => uint256) public providerAmount; - /// @dev Event emitted when a bidder is registered with their prepayed amount + /// @dev Event emitted when a bidder is registered with their deposited amount event BidderRegistered( address indexed bidder, - uint256 prepaidAmount, + uint256 depositedAmount, uint256 windowNumber ); - /// @dev Event emitted when funds are retrieved from a bidder's prepay + /// @dev Event emitted when funds are retrieved from a bidder's deposit event FundsRetrieved( bytes32 indexed commitmentDigest, address indexed bidder, @@ -62,7 +62,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { uint256 amount ); - /// @dev Event emitted when funds are retrieved from a bidder's prepay + /// @dev Event emitted when funds are retrieved from a bidder's deposit event FundsRewarded( bytes32 indexed commitmentDigest, address indexed bidder, @@ -71,7 +71,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { uint256 amount ); - /// @dev Event emitted when a bidder withdraws their prepay + /// @dev Event emitted when a bidder withdraws their deposit event BidderWithdrawal( address indexed bidder, uint256 window, @@ -86,16 +86,16 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { } /** - * @dev Receive function registers bidders and takes their prepay - * Should be removed from here in case the prepay function becomes more complex + * @dev Receive function registers bidders and takes their deposit + * Should be removed from here in case the deposit function becomes more complex */ receive() external payable { revert("Invalid call"); } /** - * @dev Constructor to initialize the contract with a minimum prepay requirement. - * @param _minAllowance The minimum prepay required for bidder registration. + * @dev Constructor to initialize the contract with a minimum deposit requirement. + * @param _minAllowance The minimum deposit required for bidder registration. * @param _feeRecipient The address that receives fee * @param _feePercent The fee percentage for protocol * @param _owner Owner of the contract, explicitly needed since contract is deployed w/ create2 factory. @@ -156,11 +156,11 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { } /** - * @dev Prepay for a specific window. - * @param window The window for which the prepay is being made. + * @dev Deposit for a specific window. + * @param window The window for which the deposit is being made. */ - function prepayAllowanceForSpecificWindow(uint256 window) external payable { - require(msg.value >= minAllowance, "Insufficient prepay"); + function depositForSpecificWindow(uint256 window) external payable { + require(msg.value >= minAllowance, "Insufficient deposit"); bidderRegistered[msg.sender] = true; lockedFunds[msg.sender][window] += msg.value; @@ -169,9 +169,9 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { } /** - * @dev Check the prepay of a bidder. + * @dev Check the deposit of a bidder. * @param bidder The address of the bidder. - * @return The prepayed amount for the bidder. + * @return The deposited amount for the bidder. */ function getAllowance( address bidder, @@ -181,9 +181,9 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { } /** - * @dev Retrieve funds from a bidder's prepay (only callable by the pre-confirmations contract). + * @dev Retrieve funds from a bidder's deposit (only callable by the pre-confirmations contract). * @dev reenterancy not necessary but still putting here for precaution - * @param commitmentDigest is the Bid ID that allows us to identify the bid, and prepayment + * @param commitmentDigest is the Bid ID that allows us to identify the bid, and deposit * @param provider The address to transfer the retrieved funds to. */ function retrieveFunds( @@ -231,9 +231,9 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { } /** - * @dev Return funds to a bidder's prepay (only callable by the pre-confirmations contract). + * @dev Return funds to a bidder's deposit (only callable by the pre-confirmations contract). * @dev reenterancy not necessary but still putting here for precaution - * @param bidID is the Bid ID that allows us to identify the bid, and prepayment + * @param bidID is the Bid ID that allows us to identify the bid, and deposit */ function unlockFunds(uint256 window, bytes32 bidID) external nonReentrant onlyPreConfirmationEngine() { BidState memory bidState = BidPayment[bidID]; @@ -249,7 +249,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /** * @dev Open a bid (only callable by the pre-confirmations contract). - * @param commitmentDigest is the Bid ID that allows us to identify the bid, and prepayment + * @param commitmentDigest is the Bid ID that allows us to identify the bid, and deposit * @param bid The bid amount. * @param bidder The address of the bidder. */ @@ -335,9 +335,9 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { "only bidder can withdraw funds from window" ); uint256 currentWindow = blockTrackerContract.getCurrentWindow(); - // withdraw is enabled only is closed and settled + // withdraw is enabled only when closed and settled require( - window + 1 < currentWindow, + window < currentWindow, "funds can only be withdrawn after the window is settled" ); uint256 amount = lockedFunds[bidder][window]; @@ -362,6 +362,6 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { require(_protocolFeeAmount > 0, "insufficient protocol fee amount"); (bool success, ) = bidder.call{value: _protocolFeeAmount}(""); - require(success, "couldn't transfer prepay to bidder"); + require(success, "couldn't transfer deposit to bidder"); } } diff --git a/contracts/interfaces/IBidderRegistry.sol b/contracts/interfaces/IBidderRegistry.sol index ddf9a18..f8dab75 100644 --- a/contracts/interfaces/IBidderRegistry.sol +++ b/contracts/interfaces/IBidderRegistry.sol @@ -30,7 +30,7 @@ interface IBidderRegistry { function getAllowance(address bidder, uint256 window) external view returns (uint256); - function prepayAllowanceForSpecificWindow(uint256 window) external payable; + function depositForSpecificWindow(uint256 window) external payable; function retrieveFunds( uint256 windowToSettle, diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index 0c52f46..3ff8156 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -41,7 +41,7 @@ contract BidderRegistryTest is Test { function testFail_BidderStakeAndRegisterMinStake() public { vm.prank(bidder); vm.expectRevert(bytes("")); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 wei}(2); + bidderRegistry.depositForSpecificWindow{value: 1 wei}(2); } function test_BidderStakeAndRegister() public { @@ -53,7 +53,7 @@ contract BidderRegistryTest is Test { emit BidderRegistered(bidder, 1 ether, nextWindow); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 1 ether}(nextWindow); bool isBidderRegistered = bidderRegistry.bidderRegistered(bidder); assertEq(isBidderRegistered, true); @@ -61,7 +61,7 @@ contract BidderRegistryTest is Test { uint256 bidderStakeStored = bidderRegistry.getAllowance(bidder, nextWindow); assertEq(bidderStakeStored, 1 ether); - // For the second prepay, calculate the new next window + // For the second deposit, calculate the new next window currentWindow = blockTracker.getCurrentWindow(); nextWindow = currentWindow + 1; @@ -69,7 +69,7 @@ contract BidderRegistryTest is Test { emit BidderRegistered(bidder, 2 ether, nextWindow); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 1 ether}(nextWindow); uint256 bidderStakeStored2 = bidderRegistry.getAllowance(bidder, nextWindow); assertEq(bidderStakeStored2, 2 ether); @@ -78,9 +78,9 @@ contract BidderRegistryTest is Test { function testFail_BidderStakeAndRegisterAlreadyRegistered() public { vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2e18 wei}(2); + bidderRegistry.depositForSpecificWindow{value: 2e18 wei}(2); vm.expectRevert(bytes("")); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 1 wei}(2); + bidderRegistry.depositForSpecificWindow{value: 1 wei}(2); } function testFail_receive() public { @@ -144,7 +144,7 @@ contract BidderRegistryTest is Test { uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 64 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 64 ether}(nextWindow); address provider = vm.addr(4); uint64 blockNumber = 66; blockTracker.addBuilderAddress("test", provider); @@ -173,7 +173,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 64 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 64 ether}(nextWindow); address provider = vm.addr(4); uint64 blockNumber = 66; @@ -197,7 +197,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; uint64 blockNumber = 66; - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(nextWindow); address provider = vm.addr(4); vm.expectRevert(bytes("")); bytes32 bidID = keccak256("1234"); @@ -213,7 +213,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; uint64 blockNumber = 66; - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(nextWindow); address provider = vm.addr(4); vm.expectRevert(bytes("")); @@ -228,7 +228,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 64 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 64 ether}(nextWindow); address provider = vm.addr(4); uint256 balanceBefore = feeRecipient.balance; bytes32 bidID = keccak256("1234"); @@ -255,7 +255,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 128 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 128 ether}(nextWindow); address provider = vm.addr(4); uint256 balanceBefore = address(provider).balance; bytes32 bidID = keccak256("1234"); @@ -277,7 +277,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 5 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 5 ether}(nextWindow); address provider = vm.addr(4); bidderRegistry.withdrawProviderAmount(payable(provider)); } @@ -289,7 +289,7 @@ contract BidderRegistryTest is Test { uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 128 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 128 ether}(nextWindow); uint256 balanceBefore = address(bidder).balance; bytes32 bidID = keccak256("1234"); uint64 blockNumber = 66; @@ -311,7 +311,7 @@ contract BidderRegistryTest is Test { vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; - bidderRegistry.prepayAllowanceForSpecificWindow{value: 5 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 5 ether}(nextWindow); vm.prank(bidderRegistry.owner()); bidderRegistry.withdrawProtocolFee(payable(address(bidder))); } @@ -322,7 +322,7 @@ contract BidderRegistryTest is Test { vm.prank(bidder); uint256 currentWindow = blockTracker.getCurrentWindow(); uint256 nextWindow = currentWindow + 1; - bidderRegistry.prepayAllowanceForSpecificWindow{value: 5 ether}(nextWindow); + bidderRegistry.depositForSpecificWindow{value: 5 ether}(nextWindow); bidderRegistry.withdrawProtocolFee(payable(address(bidder))); } } diff --git a/test/OracleTest.sol b/test/OracleTest.sol index 7f0fe97..8ae465e 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -83,7 +83,7 @@ contract OracleTest is Test { vm.deal(ownerInstance, 5 ether); vm.startPrank(ownerInstance); uint256 window = blockTracker.getCurrentWindow(); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(window+1); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(window+1); oracle = new Oracle(address(preConfCommitmentStore), address(blockTracker), ownerInstance); vm.stopPrank(); @@ -170,7 +170,7 @@ contract OracleTest is Test { vm.deal(bidder, 200000 ether); vm.startPrank(bidder); uint256 window = blockTracker.getCurrentWindow(); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); + bidderRegistry.depositForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -199,7 +199,7 @@ contract OracleTest is Test { vm.deal(bidder, 200000 ether); vm.startPrank(bidder); uint256 window = blockTracker.getCurrentWindow(); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); + bidderRegistry.depositForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -232,7 +232,7 @@ contract OracleTest is Test { vm.deal(bidder, 200000 ether); vm.startPrank(bidder); uint256 window = blockTracker.getCurrentWindow(); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); + bidderRegistry.depositForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -271,7 +271,7 @@ contract OracleTest is Test { vm.deal(bidder, 200000 ether); uint256 window = blockTracker.getWindowFromBlockNumber(blockNumber); vm.startPrank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window); + bidderRegistry.depositForSpecificWindow{value: 250 ether}(window); vm.stopPrank(); vm.deal(provider, 200000 ether); @@ -318,7 +318,7 @@ contract OracleTest is Test { vm.deal(bidder, 200000 ether); uint256 window = blockTracker.getCurrentWindow(); vm.startPrank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 250 ether}(window+1); + bidderRegistry.depositForSpecificWindow{value: 250 ether}(window+1); vm.stopPrank(); vm.deal(provider, 200000 ether); diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index d0b4239..e98a9ae 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -209,7 +209,7 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(2); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(2); // Step 1: Verify that the commitment has not been used before verifyCommitmentNotUsed( @@ -434,7 +434,7 @@ contract TestPreConfCommitmentStore is Test { vm.prank(bidder); uint256 window = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(window); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(window); // Step 1: Verify that the commitment has not been used before verifyCommitmentNotUsed( _testCommitmentAliceBob.txnHash, @@ -475,8 +475,8 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - uint256 prepayWindow = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); + uint256 depositWindow = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(depositWindow); // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( @@ -552,8 +552,8 @@ contract TestPreConfCommitmentStore is Test { (address bidder, ) = makeAddrAndKey("alice"); vm.deal(bidder, 5 ether); vm.prank(bidder); - uint256 prepayWindow = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); + uint256 depositWindow = blockTracker.getWindowFromBlockNumber(_testCommitmentAliceBob.blockNumber); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(depositWindow); // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( @@ -623,10 +623,10 @@ contract TestPreConfCommitmentStore is Test { { (address bidder, ) = makeAddrAndKey("alice"); uint64 blockNumber = 66; - uint256 prepayWindow = blockTracker.getWindowFromBlockNumber(blockNumber); + uint256 depositWindow = blockTracker.getWindowFromBlockNumber(blockNumber); vm.deal(bidder, 5 ether); vm.prank(bidder); - bidderRegistry.prepayAllowanceForSpecificWindow{value: 2 ether}(prepayWindow); + bidderRegistry.depositForSpecificWindow{value: 2 ether}(depositWindow); // Step 1: Verify that the commitment has not been used before bytes32 bidHash = verifyCommitmentNotUsed( From 71034322f3331adeeedd09c0a432e66ac5bcba49 Mon Sep 17 00:00:00 2001 From: Mikelle Date: Tue, 23 Apr 2024 19:10:29 +0200 Subject: [PATCH 24/24] allow -> deposit --- contracts/BidderRegistry.sol | 12 ++++++------ contracts/interfaces/IBidderRegistry.sol | 2 +- test/BidderRegistryTest.sol | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contracts/BidderRegistry.sol b/contracts/BidderRegistry.sol index 6eb8044..14e16ad 100644 --- a/contracts/BidderRegistry.sol +++ b/contracts/BidderRegistry.sol @@ -18,7 +18,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { uint16 public feePercent; /// @dev Minimum deposit required for registration - uint256 public minAllowance; + uint256 public minDeposit; /// @dev Amount assigned to feeRecipient uint256 public feeRecipientAmount; @@ -95,19 +95,19 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { /** * @dev Constructor to initialize the contract with a minimum deposit requirement. - * @param _minAllowance The minimum deposit required for bidder registration. + * @param _minDeposit The minimum deposit required for bidder registration. * @param _feeRecipient The address that receives fee * @param _feePercent The fee percentage for protocol * @param _owner Owner of the contract, explicitly needed since contract is deployed w/ create2 factory. */ constructor( - uint256 _minAllowance, + uint256 _minDeposit, address _feeRecipient, uint16 _feePercent, address _owner, address _blockTracker ) { - minAllowance = _minAllowance; + minDeposit = _minDeposit; feeRecipient = _feeRecipient; feePercent = _feePercent; blockTrackerContract = IBlockTracker(_blockTracker); @@ -160,7 +160,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * @param window The window for which the deposit is being made. */ function depositForSpecificWindow(uint256 window) external payable { - require(msg.value >= minAllowance, "Insufficient deposit"); + require(msg.value >= minDeposit, "Insufficient deposit"); bidderRegistered[msg.sender] = true; lockedFunds[msg.sender][window] += msg.value; @@ -173,7 +173,7 @@ contract BidderRegistry is IBidderRegistry, Ownable, ReentrancyGuard { * @param bidder The address of the bidder. * @return The deposited amount for the bidder. */ - function getAllowance( + function getDeposit( address bidder, uint256 window ) external view returns (uint256) { diff --git a/contracts/interfaces/IBidderRegistry.sol b/contracts/interfaces/IBidderRegistry.sol index f8dab75..1fbee9c 100644 --- a/contracts/interfaces/IBidderRegistry.sol +++ b/contracts/interfaces/IBidderRegistry.sol @@ -28,7 +28,7 @@ interface IBidderRegistry { function OpenBid(bytes32 commitmentDigest, uint64 bid, address bidder, uint64 blockNumber) external; - function getAllowance(address bidder, uint256 window) external view returns (uint256); + function getDeposit(address bidder, uint256 window) external view returns (uint256); function depositForSpecificWindow(uint256 window) external payable; diff --git a/test/BidderRegistryTest.sol b/test/BidderRegistryTest.sol index 3ff8156..55e269a 100644 --- a/test/BidderRegistryTest.sol +++ b/test/BidderRegistryTest.sol @@ -31,7 +31,7 @@ contract BidderRegistryTest is Test { } function test_VerifyInitialContractState() public { - assertEq(bidderRegistry.minAllowance(), 1e18 wei); + assertEq(bidderRegistry.minDeposit(), 1e18 wei); assertEq(bidderRegistry.feeRecipient(), feeRecipient); assertEq(bidderRegistry.feePercent(), feePercent); assertEq(bidderRegistry.preConfirmationsContract(), address(0)); @@ -58,7 +58,7 @@ contract BidderRegistryTest is Test { bool isBidderRegistered = bidderRegistry.bidderRegistered(bidder); assertEq(isBidderRegistered, true); - uint256 bidderStakeStored = bidderRegistry.getAllowance(bidder, nextWindow); + uint256 bidderStakeStored = bidderRegistry.getDeposit(bidder, nextWindow); assertEq(bidderStakeStored, 1 ether); // For the second deposit, calculate the new next window @@ -71,7 +71,7 @@ contract BidderRegistryTest is Test { bidderRegistry.depositForSpecificWindow{value: 1 ether}(nextWindow); - uint256 bidderStakeStored2 = bidderRegistry.getAllowance(bidder, nextWindow); + uint256 bidderStakeStored2 = bidderRegistry.getDeposit(bidder, nextWindow); assertEq(bidderStakeStored2, 2 ether); }