diff --git a/contracts/PreConfirmations.sol b/contracts/PreConfirmations.sol index 4d692b8..00a875e 100644 --- a/contracts/PreConfirmations.sol +++ b/contracts/PreConfirmations.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: BSL 1.1 pragma solidity ^0.8.15; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {IProviderRegistry} from "./interfaces/IProviderRegistry.sol"; -import {IUserRegistry} from "./interfaces/IUserRegistry.sol"; import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; /** @@ -43,8 +44,8 @@ contract PreConfCommitmentStore is Ownable { /// @dev Address of provider registry IProviderRegistry public providerRegistry; - /// @dev Address of userRegistry - IUserRegistry public userRegistry; + + IERC20 public nativeToken; /// @dev Mapping from provider to commitments count mapping(address => uint256) public commitmentsCount; @@ -106,19 +107,18 @@ 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 _userRegistry The address of the user registry. * @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 _userRegistry, address _oracle, - address _owner + address _owner, + address _nativeToken ) { oracle = _oracle; providerRegistry = IProviderRegistry(_providerRegistry); - userRegistry = IUserRegistry(_userRegistry); + nativeToken = IERC20(_nativeToken); _transferOwnership(_owner); // EIP-712 domain separator @@ -165,6 +165,7 @@ contract PreConfCommitmentStore is Ownable { ); } + /** * @dev Gives digest to be signed for pre confirmation * @param _txnHash transaction Hash. @@ -207,7 +208,7 @@ 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 user. + * @return allowance the amount extractable from the address of bid id user. */ function verifyBid( uint64 bid, @@ -217,12 +218,12 @@ contract PreConfCommitmentStore is Ownable { ) public view - returns (bytes32 messageDigest, address recoveredAddress, uint256 stake) + returns (bytes32 messageDigest, address recoveredAddress, uint256 allowance) { messageDigest = getBidHash(txnHash, bid, blockNumber); recoveredAddress = messageDigest.recover(bidSignature); - stake = userRegistry.checkStake(recoveredAddress); - require(stake > (10 * bid), "Invalid bid"); + allowance = nativeToken.allowance(recoveredAddress, address(this)); + require(allowance >= bid, "Insufficient allowance"); } /** @@ -286,7 +287,7 @@ contract PreConfCommitmentStore is Ownable { bytes calldata bidSignature, bytes memory commitmentSignature ) public returns (bytes32 commitmentIndex) { - (bytes32 bHash, address bidderAddress, uint256 stake) = verifyBid( + (bytes32 bHash, address bidderAddress, uint256 allowance) = verifyBid( bid, blockNumber, txnHash, @@ -304,7 +305,7 @@ contract PreConfCommitmentStore is Ownable { address commiterAddress = preConfHash.recover(commitmentSignature); - require(stake > (10 * bid), "Stake too low"); + require(allowance > bid, "allowance too low"); PreConfCommitment memory newCommitment = PreConfCommitment( false, @@ -321,7 +322,6 @@ contract PreConfCommitmentStore is Ownable { commitmentIndex = getCommitmentIndex(newCommitment); - // Store commitment commitments[commitmentIndex] = newCommitment; @@ -421,11 +421,7 @@ contract PreConfCommitmentStore is Ownable { commitments[commitmentIndex].commitmentUsed = true; commitmentsCount[commitment.commiter] -= 1; - userRegistry.retrieveFunds( - commitment.bidder, - commitment.bid, - payable(commitment.commiter) - ); + nativeToken.transferFrom(commitment.bidder, commitment.commiter, commitment.bid); } /** @@ -446,14 +442,6 @@ contract PreConfCommitmentStore is Ownable { providerRegistry = IProviderRegistry(newProviderRegistry); } - /** - * @dev Updates the address of the user registry. - * @param newUserRegistry The new user registry address. - */ - function updateUserRegistry(address newUserRegistry) external onlyOwner { - userRegistry = IUserRegistry(newUserRegistry); - } - /** * @dev Internal Function to convert bytes32 to hex string without 0x * @param _bytes32 the byte array to convert to string diff --git a/contracts/UserRegistry.sol b/contracts/UserRegistry.sol deleted file mode 100644 index d97b4b3..0000000 --- a/contracts/UserRegistry.sol +++ /dev/null @@ -1,227 +0,0 @@ -// SPDX-License-Identifier: BSL 1.1 -pragma solidity ^0.8.15; - -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; -import {IUserRegistry} from "./interfaces/IUserRegistry.sol"; - -/// @title User Registry -/// @author Kartik Chopra -/// @notice This contract is for user registry and staking. -contract UserRegistry is IUserRegistry, Ownable, ReentrancyGuard { - /// @dev For improved precision - uint256 constant PRECISION = 10 ** 25; - uint256 constant PERCENT = 100 * PRECISION; - - /// @dev Fee percent that would be taken by protocol when provider is slashed - uint16 public feePercent; - - /// @dev Minimum stake required for registration - uint256 public minStake; - - /// @dev Amount assigned to feeRecipient - uint256 public feeRecipientAmount; - - /// @dev protocol fee, left over amount when there is no fee recipient assigned - uint256 public protocolFeeAmount; - - /// @dev Address of the pre-confirmations contract - address public preConfirmationsContract; - - /// @dev Fee recipient - address public feeRecipient; - - /// @dev Mapping for if user is registered - mapping(address => bool) public userRegistered; - - /// @dev Mapping from user addresses to their staked amount - mapping(address => uint256) public userStakes; - - /// @dev Amount assigned to users - mapping(address => uint256) public providerAmount; - - /// @dev Event emitted when a user is registered with their staked amount - event UserRegistered(address indexed user, uint256 stakedAmount); - - /// @dev Event emitted when funds are retrieved from a user's stake - event FundsRetrieved(address indexed user, uint256 amount); - - /** - * @dev Fallback function to revert all calls, ensuring no unintended interactions. - */ - fallback() external payable { - revert("Invalid call"); - } - - /** - * @dev Receive function registers users and takes their stake - * Should be removed from here in case the registerAndStake function becomes more complex - */ - receive() external payable { - registerAndStake(); - } - - /** - * @dev Constructor to initialize the contract with a minimum stake requirement. - * @param _minStake The minimum stake required for user 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 _minStake, - address _feeRecipient, - uint16 _feePercent, - address _owner - ) { - minStake = _minStake; - feeRecipient = _feeRecipient; - feePercent = _feePercent; - _transferOwnership(_owner); - } - - /** - * @dev Modifier to restrict a function to only be callable by the pre-confirmations contract. - */ - modifier onlyPreConfirmationEngine() { - require( - msg.sender == preConfirmationsContract, - "Only the pre-confirmations contract can call this function" - ); - _; - } - - /** - * @dev Sets the pre-confirmations contract address. Can only be called by the owner. - * @param contractAddress The address of the pre-confirmations contract. - */ - function setPreconfirmationsContract( - address contractAddress - ) external onlyOwner { - require( - preConfirmationsContract == address(0), - "Preconfirmations Contract is already set and cannot be changed." - ); - preConfirmationsContract = contractAddress; - } - - /** - * @dev Get the amount assigned to a provider. - */ - function getProviderAmount(address provider) external view returns (uint256) { - return providerAmount[provider]; - } - - /** - * @dev Internal function for user registration and staking. - */ - function registerAndStake() public payable { - require(!userRegistered[msg.sender], "User already registered"); - require(msg.value >= minStake, "Insufficient stake"); - - userStakes[msg.sender] = msg.value; - userRegistered[msg.sender] = true; - - emit UserRegistered(msg.sender, msg.value); - } - - /** - * @dev Check the stake of a user. - * @param user The address of the user. - * @return The staked amount for the user. - */ - function checkStake(address user) external view returns (uint256) { - return userStakes[user]; - } - - /** - * @dev Retrieve funds from a user's stake (only callable by the pre-confirmations contract). - * @dev reenterancy not necessary but still putting here for precaution - * @param user The address of the user. - * @param amt The amount to retrieve from the user's stake. - * @param provider The address to transfer the retrieved funds to. - */ - function retrieveFunds( - address user, - uint256 amt, - address payable provider - ) external nonReentrant onlyPreConfirmationEngine { - uint256 amount = userStakes[user]; - require( - amount >= amt, - "Amount to retrieve bigger than available funds" - ); - userStakes[user] -= amt; - - uint256 feeAmt = (amt * uint256(feePercent) * PRECISION) / PERCENT; - uint256 amtMinusFee = amt - feeAmt; - - if (feeRecipient != address(0)) { - feeRecipientAmount += feeAmt; - } else { - protocolFeeAmount += feeAmt; - } - - providerAmount[provider] += amtMinusFee; - - emit FundsRetrieved(user, amount); - } - - /** - * @notice Sets the new fee recipient - * @dev onlyOwner restriction - * @param newFeeRecipient The address to transfer the slashed funds to. - */ - function setNewFeeRecipient(address newFeeRecipient) external onlyOwner { - feeRecipient = newFeeRecipient; - } - - /** - * @notice Sets the new fee recipient - * @dev onlyOwner restriction - * @param newFeePercent this is the new fee percent - */ - function setNewFeePercent(uint16 newFeePercent) external onlyOwner { - feePercent = newFeePercent; - } - - function withdrawFeeRecipientAmount() external nonReentrant { - uint256 amount = feeRecipientAmount; - feeRecipientAmount = 0; - require(amount > 0, "fee recipient amount Amount is zero"); - (bool successFee, ) = feeRecipient.call{value: amount}(""); - require(successFee, "Couldn't transfer to fee Recipient"); - } - - function withdrawProviderAmount( - address payable provider - ) external nonReentrant { - uint256 amount = providerAmount[provider]; - providerAmount[provider] = 0; - - require(amount > 0, "provider Amount is zero"); - (bool success, ) = provider.call{value: amount}(""); - require(success, "Couldn't transfer to provider"); - } - - function withdrawStakedAmount(address payable user) external nonReentrant { - uint256 stake = userStakes[user]; - userStakes[user] = 0; - require(msg.sender == user, "Only user can unstake"); - require(stake > 0, "Provider Staked Amount is zero"); - - (bool success, ) = user.call{value: stake}(""); - require(success, "Couldn't transfer stake to user"); - } - - function withdrawProtocolFee( - address payable user - ) external onlyOwner nonReentrant { - uint256 _protocolFeeAmount = protocolFeeAmount; - protocolFeeAmount = 0; - require(_protocolFeeAmount > 0, "In sufficient protocol fee amount"); - - (bool success, ) = user.call{value: _protocolFeeAmount}(""); - require(success, "Couldn't transfer stake to user"); - } -} diff --git a/contracts/interfaces/IPreConfirmations.sol b/contracts/interfaces/IPreConfirmations.sol index 4c1353b..560b3ef 100644 --- a/contracts/interfaces/IPreConfirmations.sol +++ b/contracts/interfaces/IPreConfirmations.sol @@ -55,7 +55,7 @@ interface IPreConfCommitmentStore { uint64 blockNumber, string memory txnHash, bytes calldata bidSignature - ) external view returns (bytes32 messageDigest, address recoveredAddress, uint256 stake); + ) external view returns (bytes32 messageDigest, address recoveredAddress, uint256 allowance); function storeCommitment( uint64 bid, @@ -79,7 +79,6 @@ interface IPreConfCommitmentStore { function updateProviderRegistry(address newProviderRegistry) external; - function updateUserRegistry(address newUserRegistry) external; // Public functions that can be included if they are meant to be called from other contracts diff --git a/contracts/interfaces/IUserRegistry.sol b/contracts/interfaces/IUserRegistry.sol deleted file mode 100644 index 2a33ad9..0000000 --- a/contracts/interfaces/IUserRegistry.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: BSL 1.1 -pragma solidity ^0.8.15; - -interface IUserRegistry { - struct PreConfCommitment { - string txnHash; - uint64 bid; - uint64 blockNumber; - string bidHash; - string bidSignature; - string commitmentHash; - string commitmentSignature; - } - - function registerAndStake() external payable; - - function checkStake(address user) external view returns (uint256); - - function retrieveFunds( - address user, - uint256 amt, - address payable provider - ) external; -} diff --git a/scripts/DeployScripts.s.sol b/scripts/DeployScripts.s.sol index 8598ccb..6864036 100644 --- a/scripts/DeployScripts.s.sol +++ b/scripts/DeployScripts.s.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import "forge-std/Script.sol"; -import "contracts/UserRegistry.sol"; import "contracts/ProviderRegistry.sol"; import "contracts/PreConfirmations.sol"; import "contracts/Oracle.sol"; @@ -47,22 +46,19 @@ contract DeployScript is Script, Create2Deployer { // Forge deploy with salt uses create2 proxy from https://github.com/primevprotocol/deterministic-deployment-proxy bytes32 salt = 0x8989000000000000000000000000000000000000000000000000000000000000; - - UserRegistry userRegistry = new UserRegistry{salt: salt}(minStake, feeRecipient, feePercent, msg.sender); - console.log("UserRegistry deployed to:", address(userRegistry)); + + // NativeToken will be set in future once we know where it's getting deployed + address NativeToken = address(0x000); 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(userRegistry), feeRecipient, msg.sender); + PreConfCommitmentStore preConfCommitmentStore = new PreConfCommitmentStore{salt: salt}(address(providerRegistry), feeRecipient, msg.sender, NativeToken); console.log("PreConfCommitmentStore deployed to:", address(preConfCommitmentStore)); providerRegistry.setPreconfirmationsContract(address(preConfCommitmentStore)); console.log("ProviderRegistry updated with PreConfCommitmentStore address:", address(preConfCommitmentStore)); - userRegistry.setPreconfirmationsContract(address(preConfCommitmentStore)); - console.log("UserRegistry updated with PreConfCommitmentStore address:", address(preConfCommitmentStore)); - Oracle oracle = new Oracle{salt: salt}(address(preConfCommitmentStore), nextRequestedBlockNumber, msg.sender); console.log("Oracle deployed to:", address(oracle)); diff --git a/test/DummyERC20.sol b/test/DummyERC20.sol new file mode 100644 index 0000000..f7aa4bd --- /dev/null +++ b/test/DummyERC20.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract DummyERC20 is ERC20 { + constructor(string memory name, string memory symbol) ERC20(name, symbol) {} + + function mint(address to, uint256 amount) public { + _mint(to, amount); + } +} diff --git a/test/OracleTest.sol b/test/OracleTest.sol index f6a1c9b..b5ad104 100644 --- a/test/OracleTest.sol +++ b/test/OracleTest.sol @@ -6,7 +6,8 @@ import "../contracts/Oracle.sol"; import "../contracts/PreConfirmations.sol"; import "../contracts/interfaces/IPreConfirmations.sol"; import "../contracts/ProviderRegistry.sol"; -import "../contracts/UserRegistry.sol"; +import "./DummyERC20.sol"; + contract OracleTest is Test { address internal owner; @@ -19,7 +20,7 @@ contract OracleTest is Test { ProviderRegistry internal providerRegistry; uint256 testNumber; uint64 testNumber2; - UserRegistry internal userRegistry; + DummyERC20 internal dummyToken; // Events to match against @@ -35,32 +36,36 @@ contract OracleTest is Test { minStake = 1e18 wei; feeRecipient = vm.addr(9); + // Deploy the dummy ERC20 token + dummyToken = new DummyERC20("DummyToken", "DTK"); + // Optionally mint some tokens for testing + dummyToken.mint(address(this), 10000 ether); + providerRegistry = new ProviderRegistry( minStake, feeRecipient, feePercent, address(this) ); - userRegistry = new UserRegistry(minStake, feeRecipient, feePercent, address(this)); preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry - address(userRegistry), // User Registry feeRecipient, // Oracle - address(this) // Owner + address(this), // Owner + address(dummyToken) ); address ownerInstance = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3; + dummyToken.transfer(ownerInstance, 5 ether); vm.deal(ownerInstance, 5 ether); vm.startPrank(ownerInstance); - userRegistry.registerAndStake{value: 2 ether}(); + dummyToken.approve(address(preConfCommitmentStore), 2 ether); oracle = new Oracle(address(preConfCommitmentStore), 2, ownerInstance); oracle.addBuilderAddress("mev builder", ownerInstance); vm.stopPrank(); preConfCommitmentStore.updateOracle(address(oracle)); - userRegistry.setPreconfirmationsContract(address(preConfCommitmentStore)); providerRegistry.setPreconfirmationsContract(address(preConfCommitmentStore)); } @@ -98,11 +103,11 @@ contract OracleTest is Test { assertEq(oracle.blockBuilderNameToAddress("zk builder"), builder4); vm.stopPrank(); - vm.deal(user, 1000 ether); + vm.deal(provider, 1000 ether); vm.startPrank(user); - userRegistry.registerAndStake{value: 250 ether }(); + dummyToken.approve(address(preConfCommitmentStore), 2 ether); vm.stopPrank(); vm.startPrank(provider); @@ -115,7 +120,6 @@ contract OracleTest is Test { txnList[0] = string(abi.encodePacked(keccak256("0xkartik"))); oracle.receiveBlockData(txnList, 2, "primev builder"); - assertEq(userRegistry.getProviderAmount(provider), 0); assertEq(providerRegistry.checkStake(provider), 250 ether); } @@ -190,11 +194,13 @@ contract OracleTest is Test { (address user, uint256 userPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("kartik"); - vm.deal(user, 200000 ether); + + dummyToken.mint(user, 200000 ether); vm.startPrank(user); - userRegistry.registerAndStake{value: 250 ether }(); + dummyToken.approve(address(preConfCommitmentStore), 2 ether); vm.stopPrank(); + vm.deal(provider, 200000 ether); vm.startPrank(provider); providerRegistry.registerAndStake{value: 250 ether}(); @@ -209,7 +215,7 @@ contract OracleTest is Test { bytes32[] memory commitmentHashes = preConfCommitmentStore.getCommitmentsByBlockNumber(blockNumber); assertEq(commitmentHashes.length, 1); - assertEq(userRegistry.getProviderAmount(provider), bid); + assertEq(200000 ether - dummyToken.balanceOf(user), bid); } @@ -223,11 +229,11 @@ contract OracleTest is Test { (address user, uint256 userPk) = makeAddrAndKey("alice"); (address provider, uint256 providerPk) = makeAddrAndKey("bob"); - vm.deal(user, 200000 ether); + dummyToken.mint(user, 200000 ether); vm.deal(provider, 200000 ether); vm.startPrank(user); - userRegistry.registerAndStake{value: 250 ether }(); + dummyToken.approve(address(preConfCommitmentStore), 250 ether); vm.stopPrank(); vm.startPrank(provider); @@ -246,14 +252,11 @@ contract OracleTest is Test { bytes32[] memory commitmentHashes = preConfCommitmentStore.getCommitmentsByBlockNumber(blockNumber); assertEq(commitmentHashes.length, 1); - - // Ensuring no rewards - assertEq(userRegistry.getProviderAmount(provider), 0); - + // Detect slashing uint256 postSlashStake = providerRegistry.checkStake(provider); assertEq(postSlashStake + bid, ogStake); - assertEq(userRegistry.checkStake(user), 250 ether); + assertEq(dummyToken.allowance(user, address(preConfCommitmentStore)), 250 ether); } diff --git a/test/PreConfirmationConfTest.sol b/test/PreConfirmationConfTest.sol index b152bb6..ddd2d6f 100644 --- a/test/PreConfirmationConfTest.sol +++ b/test/PreConfirmationConfTest.sol @@ -6,7 +6,8 @@ import "forge-std/Test.sol"; import {PreConfCommitmentStore} from "../contracts/PreConfirmations.sol"; import "../contracts/ProviderRegistry.sol"; -import "../contracts/UserRegistry.sol"; +import "./DummyERC20.sol"; + contract TestPreConfCommitmentStore is Test { PreConfCommitmentStore internal preConfCommitmentStore; @@ -17,13 +18,19 @@ contract TestPreConfCommitmentStore is Test { ProviderRegistry internal providerRegistry; uint256 testNumber; uint64 testNumber2; - - UserRegistry internal userRegistry; + DummyERC20 internal dummyToken; function setUp() public { testNumber = 2; testNumber2 = 2; + + // Deploy the dummy ERC20 token + dummyToken = new DummyERC20("DummyToken", "DTK"); + // Optionally mint some tokens for testing + dummyToken.mint(address(this), 1000 ether); + + feePercent = 10; minStake = 1e18 wei; feeRecipient = vm.addr(9); @@ -33,13 +40,12 @@ contract TestPreConfCommitmentStore is Test { feePercent, address(this) ); - userRegistry = new UserRegistry(minStake, feeRecipient, feePercent, address(this)); preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry - address(userRegistry), // User Registry feeRecipient, // Oracle - address(this) // Owner + address(this), // Owner + address(dummyToken) ); } @@ -49,10 +55,6 @@ contract TestPreConfCommitmentStore is Test { address(preConfCommitmentStore.providerRegistry()), address(providerRegistry) ); - assertEq( - address(preConfCommitmentStore.userRegistry()), - address(userRegistry) - ); } function test_CreateCommitment() public { @@ -68,10 +70,11 @@ contract TestPreConfCommitmentStore is Test { vm.deal(user, 200000 ether); vm.prank(user); - userRegistry.registerAndStake{value: 1e18 wei}(); - (bytes32 digest, address recoveredAddress, uint256 stake) = preConfCommitmentStore.verifyBid(200 wei, 3000, "0xkartik", signature); + dummyToken.approve(address(preConfCommitmentStore), 1e18 wei); + + (bytes32 digest, address recoveredAddress, uint256 allowance) = preConfCommitmentStore.verifyBid(200 wei, 3000, "0xkartik", signature); - assertEq(stake, 1e18 wei); + assertEq(allowance, 1e18 wei); assertEq(user, recoveredAddress); assertEq(digest, bidHash); @@ -92,11 +95,6 @@ contract TestPreConfCommitmentStore is Test { ); } - function test_UpdateUserRegistry() public { - preConfCommitmentStore.updateUserRegistry(feeRecipient); - assertEq(address(preConfCommitmentStore.userRegistry()), feeRecipient); - } - function test_GetBidHash() public { string memory hash = "0xkartik"; @@ -144,7 +142,8 @@ contract TestPreConfCommitmentStore is Test { address signer = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3; vm.deal(signer, 5 ether); vm.prank(signer); - userRegistry.registerAndStake{value: 2 ether}(); + dummyToken.approve(address(preConfCommitmentStore), 2 ether); + string memory txnHash = "0xkartik"; bytes memory signature = "0xb170d082db1bf77fa0b589b9438444010dcb1e6dd326b661b02eb92abe4c066e243bb0d214b01667750ba2c53ff1ab445fd784b441dbc1f30280c379f002cc571c"; @@ -285,7 +284,8 @@ contract TestPreConfCommitmentStore is Test { address signer = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3; vm.deal(signer, 5 ether); vm.prank(signer); - userRegistry.registerAndStake{value: 2 ether}(); + dummyToken.approve(address(preConfCommitmentStore), 2 ether); + string memory txnHash = "0xkartik"; bytes memory signature = "0xb170d082db1bf77fa0b589b9438444010dcb1e6dd326b661b02eb92abe4c066e243bb0d214b01667750ba2c53ff1ab445fd784b441dbc1f30280c379f002cc571c"; @@ -325,7 +325,8 @@ contract TestPreConfCommitmentStore is Test { address signer = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3; vm.deal(signer, 5 ether); vm.prank(signer); - userRegistry.registerAndStake{value: 2 ether}(); + dummyToken.approve(address(preConfCommitmentStore), 2 ether); + string memory txnHash = "0xkartik"; bytes memory signature = "0xb170d082db1bf77fa0b589b9438444010dcb1e6dd326b661b02eb92abe4c066e243bb0d214b01667750ba2c53ff1ab445fd784b441dbc1f30280c379f002cc571c"; @@ -386,10 +387,13 @@ contract TestPreConfCommitmentStore is Test { function test_InitiateReward() public { // Assuming you have a stored commitment { + dummyToken.transfer(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3, 5 ether); address signer = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3; vm.deal(signer, 5 ether); vm.prank(signer); - userRegistry.registerAndStake{value: 2 ether}(); + + dummyToken.approve(address(preConfCommitmentStore), 2 ether); + string memory txnHash = "0xkartik"; bytes memory signature = "0xb170d082db1bf77fa0b589b9438444010dcb1e6dd326b661b02eb92abe4c066e243bb0d214b01667750ba2c53ff1ab445fd784b441dbc1f30280c379f002cc571c"; @@ -430,9 +434,6 @@ contract TestPreConfCommitmentStore is Test { commitmentSignature ); - userRegistry.setPreconfirmationsContract( - address(preConfCommitmentStore) - ); vm.deal(commiter, 5 ether); vm.prank(commiter); providerRegistry.registerAndStake{value: 4 ether}(); diff --git a/test/ProviderRegistryTest.sol b/test/ProviderRegistryTest.sol index 6b8a028..02c9a41 100644 --- a/test/ProviderRegistryTest.sol +++ b/test/ProviderRegistryTest.sol @@ -2,8 +2,9 @@ pragma solidity ^0.8.20; import "forge-std/Test.sol"; +import "./DummyERC20.sol"; + import {ProviderRegistry} from "../contracts/ProviderRegistry.sol"; -import {UserRegistry} from "../contracts/UserRegistry.sol"; import {PreConfCommitmentStore} from "../contracts/PreConfirmations.sol"; contract ProviderRegistryTest is Test { @@ -13,7 +14,6 @@ contract ProviderRegistryTest is Test { uint256 internal minStake; address internal provider; address internal feeRecipient; - UserRegistry userRegistry; PreConfCommitmentStore preConfCommitmentStore; event ProviderRegistered(address indexed provider, uint256 stakedAmount); @@ -24,19 +24,24 @@ contract ProviderRegistryTest is Test { minStake = 1e18 wei; feeRecipient = vm.addr(9); + + // Deploy the dummy ERC20 token + DummyERC20 dummyToken = new DummyERC20("DummyToken", "DTK"); + // Optionally mint some tokens for testing + dummyToken.mint(address(this), 1000 ether); + providerRegistry = new ProviderRegistry( minStake, feeRecipient, feePercent, address(this) ); - userRegistry = new UserRegistry(minStake, feeRecipient, feePercent, address(this)); preConfCommitmentStore = new PreConfCommitmentStore( address(providerRegistry), // Provider Registry - address(userRegistry), // User Registry feeRecipient, // Oracle - address(this) // Owner + address(this), // Owner + address(dummyToken) ); provider = vm.addr(1); diff --git a/test/UserRegistryTest.sol b/test/UserRegistryTest.sol deleted file mode 100644 index 9521660..0000000 --- a/test/UserRegistryTest.sol +++ /dev/null @@ -1,275 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import "forge-std/Test.sol"; -import {UserRegistry} from "../contracts/UserRegistry.sol"; - -contract UserRegistryTest is Test { - uint256 testNumber; - UserRegistry internal userRegistry; - uint16 internal feePercent; - uint256 internal minStake; - address internal user; - address internal feeRecipient; - - /// @dev Event emitted when a user is registered with their staked amount - event UserRegistered(address indexed user, uint256 stakedAmount); - - function setUp() public { - testNumber = 42; - feePercent = 10; - minStake = 1e18 wei; - feeRecipient = vm.addr(9); - - userRegistry = new UserRegistry(minStake, feeRecipient, feePercent, address(this)); - - user = vm.addr(1); - vm.deal(user, 100 ether); - vm.deal(address(this), 100 ether); - } - - function test_VerifyInitialContractState() public { - assertEq(userRegistry.minStake(), 1e18 wei); - assertEq(userRegistry.feeRecipient(), feeRecipient); - assertEq(userRegistry.feePercent(), feePercent); - assertEq(userRegistry.preConfirmationsContract(), address(0)); - assertEq(userRegistry.userRegistered(user), false); - } - - function testFail_UserStakeAndRegisterMinStake() public { - vm.prank(user); - vm.expectRevert(bytes("")); - userRegistry.registerAndStake{value: 1 wei}(); - } - - function test_UserStakeAndRegister() public { - vm.prank(user); - vm.expectEmit(true, false, false, true); - - emit UserRegistered(user, 1e18 wei); - - userRegistry.registerAndStake{value: 1e18 wei}(); - - bool isUserRegistered = userRegistry.userRegistered(user); - assertEq(isUserRegistered, true); - - uint256 userStakeStored = userRegistry.checkStake(user); - assertEq(userStakeStored, 1e18 wei); - } - - function testFail_UserStakeAndRegisterAlreadyRegistered() public { - vm.prank(user); - userRegistry.registerAndStake{value: 2e18 wei}(); - vm.expectRevert(bytes("")); - userRegistry.registerAndStake{value: 1 wei}(); - } - - function testFail_receive() public { - vm.prank(user); - vm.expectRevert(bytes("")); - (bool success, ) = address(userRegistry).call{value: 1 wei}(""); - require(success, "couldn't transfer to user"); - } - - function testFail_fallback() public { - vm.prank(user); - vm.expectRevert(bytes("")); - (bool success, ) = address(userRegistry).call{value: 1 wei}(""); - require(success, "couldn't transfer to user"); - } - - function test_SetNewFeeRecipient() public { - address newRecipient = vm.addr(2); - vm.prank(address(this)); - userRegistry.setNewFeeRecipient(newRecipient); - - assertEq(userRegistry.feeRecipient(), newRecipient); - } - - function testFail_SetNewFeeRecipient() public { - address newRecipient = vm.addr(2); - vm.expectRevert(bytes("")); - userRegistry.setNewFeeRecipient(newRecipient); - } - - function test_SetNewFeePercent() public { - vm.prank(address(this)); - userRegistry.setNewFeePercent(uint16(25)); - - assertEq(userRegistry.feePercent(), uint16(25)); - } - - function testFail_SetNewFeePercent() public { - vm.expectRevert(bytes("")); - userRegistry.setNewFeePercent(uint16(25)); - } - - function test_SetPreConfContract() public { - vm.prank(address(this)); - address newPreConfContract = vm.addr(3); - userRegistry.setPreconfirmationsContract(newPreConfContract); - - assertEq(userRegistry.preConfirmationsContract(), newPreConfContract); - } - - function testFail_SetPreConfContract() public { - vm.prank(address(this)); - vm.expectRevert(bytes("")); - userRegistry.setPreconfirmationsContract(address(0)); - } - - function test_shouldRetrieveFunds() public { - userRegistry.setPreconfirmationsContract(address(this)); - vm.prank(user); - userRegistry.registerAndStake{value: 2 ether}(); - address provider = vm.addr(4); - - userRegistry.retrieveFunds(user, 1 ether, payable(provider)); - uint256 providerAmount = userRegistry.providerAmount(provider); - uint256 feeRecipientAmount = userRegistry.feeRecipientAmount(); - - assertEq(providerAmount, 900000000000000000); - assertEq(feeRecipientAmount, 100000000000000000); - assertEq(userRegistry.userStakes(user), 1 ether); - } - - function test_shouldRetrieveFundsWithoutFeeRecipient() public { - vm.prank(address(this)); - uint256 feerecipientValueBefore = userRegistry.feeRecipientAmount(); - - userRegistry.setNewFeeRecipient(address(0)); - userRegistry.setPreconfirmationsContract(address(this)); - - vm.prank(user); - userRegistry.registerAndStake{value: 2 ether}(); - address provider = vm.addr(4); - - userRegistry.retrieveFunds(user, 1 ether, payable(provider)); - - uint256 feerecipientValueAfter = userRegistry.feeRecipientAmount(); - uint256 providerAmount = userRegistry.providerAmount(provider); - - assertEq(providerAmount, 900000000000000000); - assertEq(feerecipientValueAfter, feerecipientValueBefore); - - assertEq(userRegistry.userStakes(user), 1 ether); - } - - function testFail_shouldRetrieveFundsNotPreConf() public { - vm.prank(user); - userRegistry.registerAndStake{value: 2 ether}(); - address provider = vm.addr(4); - vm.expectRevert(bytes("")); - userRegistry.retrieveFunds(user, 1 ether, payable(provider)); - } - - function testFail_shouldRetrieveFundsGreaterThanStake() public { - vm.prank(address(this)); - userRegistry.setPreconfirmationsContract(address(this)); - - vm.prank(user); - userRegistry.registerAndStake{value: 2 ether}(); - - address provider = vm.addr(4); - vm.expectRevert(bytes("")); - vm.prank(address(this)); - - userRegistry.retrieveFunds(user, 3 ether, payable(provider)); - } - - function test_withdrawFeeRecipientAmount() public { - userRegistry.setPreconfirmationsContract(address(this)); - vm.prank(user); - userRegistry.registerAndStake{value: 2 ether}(); - address provider = vm.addr(4); - uint256 balanceBefore = feeRecipient.balance; - userRegistry.retrieveFunds(user, 1 ether, payable(provider)); - userRegistry.withdrawFeeRecipientAmount(); - uint256 balanceAfter = feeRecipient.balance; - assertEq(balanceAfter - balanceBefore, 100000000000000000); - assertEq(userRegistry.feeRecipientAmount(), 0); - } - - function testFail_withdrawFeeRecipientAmount() public { - userRegistry.setPreconfirmationsContract(address(this)); - userRegistry.withdrawFeeRecipientAmount(); - } - - function test_withdrawProviderAmount() public { - userRegistry.setPreconfirmationsContract(address(this)); - vm.prank(user); - userRegistry.registerAndStake{value: 5 ether}(); - address provider = vm.addr(4); - uint256 balanceBefore = address(provider).balance; - userRegistry.retrieveFunds(user, 2 ether, payable(provider)); - userRegistry.withdrawProviderAmount(payable(provider)); - uint256 balanceAfter = address(provider).balance; - assertEq(balanceAfter - balanceBefore, 1800000000000000000); - assertEq(userRegistry.providerAmount(provider), 0); - } - - function testFail_withdrawProviderAmount() public { - userRegistry.setPreconfirmationsContract(address(this)); - vm.prank(user); - userRegistry.registerAndStake{value: 5 ether}(); - address provider = vm.addr(4); - userRegistry.withdrawProviderAmount(payable(provider)); - } - - function test_withdrawStakedAmount() public { - userRegistry.setPreconfirmationsContract(address(this)); - vm.prank(user); - userRegistry.registerAndStake{value: 5 ether}(); - uint256 balanceBefore = address(user).balance; - vm.prank(user); - userRegistry.withdrawStakedAmount(payable(user)); - uint256 balanceAfter = address(user).balance; - assertEq(balanceAfter - balanceBefore, 5 ether); - assertEq(userRegistry.userStakes(user), 0); - } - - function testFail_withdrawStakedAmountNotOwner() public { - userRegistry.setPreconfirmationsContract(address(this)); - vm.prank(user); - userRegistry.registerAndStake{value: 5 ether}(); - userRegistry.withdrawStakedAmount(payable(user)); - } - - function testFail_withdrawStakedAmountStakeZero() public { - userRegistry.setPreconfirmationsContract(address(this)); - vm.prank(user); - userRegistry.withdrawStakedAmount(payable(user)); - } - - function test_withdrawProtocolFee() public { - address provider = vm.addr(4); - userRegistry.setPreconfirmationsContract(address(this)); - userRegistry.setNewFeeRecipient(address(0)); - vm.prank(user); - userRegistry.registerAndStake{value: 5 ether}(); - uint256 balanceBefore = address(user).balance; - userRegistry.retrieveFunds(user, 2 ether, payable(provider)); - vm.prank(userRegistry.owner()); - userRegistry.withdrawProtocolFee(payable(address(user))); - uint256 balanceAfter = address(user).balance; - assertEq(balanceAfter - balanceBefore, 200000000000000000); - assertEq(userRegistry.protocolFeeAmount(), 0); - } - - function testFail_withdrawProtocolFee() public { - userRegistry.setPreconfirmationsContract(address(this)); - userRegistry.setNewFeeRecipient(address(0)); - vm.prank(user); - userRegistry.registerAndStake{value: 5 ether}(); - vm.prank(userRegistry.owner()); - userRegistry.withdrawProtocolFee(payable(address(user))); - } - - function testFail_withdrawProtocolFeeNotOwner() public { - userRegistry.setPreconfirmationsContract(address(this)); - userRegistry.setNewFeeRecipient(address(0)); - vm.prank(user); - userRegistry.registerAndStake{value: 5 ether}(); - userRegistry.withdrawProtocolFee(payable(address(user))); - } -}