From d570ca16efe2ff21235e769441ec35e8a08e795d Mon Sep 17 00:00:00 2001 From: Jem <0x0xjem@gmail.com> Date: Fri, 21 Jun 2024 15:25:39 +0400 Subject: [PATCH] Add tests for Baseline Allowlist --- script/salts/test/TestSalts.s.sol | 5 +- .../Allowlist/BaselineAllowlistTest.sol | 42 +++++++ .../BaselineV2/Allowlist/onBid.t.sol | 118 ++++++++++++++++++ .../BaselineV2/Allowlist/onCreate.t.sol | 51 ++++++++ .../BaselineV2/Allowlist/setMerkleRoot.t.sol | 95 ++++++++++++++ .../BaselineCappedAllowlistTest.sol | 8 +- .../BaselineV2/CappedAllowlist/onBid.t.sol | 10 +- .../BaselineV2/CappedAllowlist/onCreate.t.sol | 3 +- .../CappedAllowlist/setMerkleRoot.t.sol | 9 +- 9 files changed, 319 insertions(+), 22 deletions(-) create mode 100644 test/callbacks/liquidity/BaselineV2/Allowlist/BaselineAllowlistTest.sol create mode 100644 test/callbacks/liquidity/BaselineV2/Allowlist/onBid.t.sol create mode 100644 test/callbacks/liquidity/BaselineV2/Allowlist/onCreate.t.sol create mode 100644 test/callbacks/liquidity/BaselineV2/Allowlist/setMerkleRoot.t.sol diff --git a/script/salts/test/TestSalts.s.sol b/script/salts/test/TestSalts.s.sol index 50536ce5..9250ac1b 100644 --- a/script/salts/test/TestSalts.s.sol +++ b/script/salts/test/TestSalts.s.sol @@ -570,9 +570,8 @@ contract TestSalts is Script, WithEnvironment, Permit2User, WithSalts, TestConst // Get the salt bytes memory callbackArgs = abi.encode(_AUCTION_HOUSE, _BASELINE_KERNEL, _BASELINE_QUOTE_TOKEN, _OWNER); - (string memory callbackBytecodePath, bytes32 callbackBytecodeHash) = _writeBytecode( - "BaselineAllowlist", type(BALwithAllowlist).creationCode, callbackArgs - ); + (string memory callbackBytecodePath, bytes32 callbackBytecodeHash) = + _writeBytecode("BaselineAllowlist", type(BALwithAllowlist).creationCode, callbackArgs); _setTestSalt(callbackBytecodePath, "EF", "BaselineAllowlist", callbackBytecodeHash); } diff --git a/test/callbacks/liquidity/BaselineV2/Allowlist/BaselineAllowlistTest.sol b/test/callbacks/liquidity/BaselineV2/Allowlist/BaselineAllowlistTest.sol new file mode 100644 index 00000000..a7184f54 --- /dev/null +++ b/test/callbacks/liquidity/BaselineV2/Allowlist/BaselineAllowlistTest.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +// Test scaffolding +import {BaselineAxisLaunchTest} from + "test/callbacks/liquidity/BaselineV2/BaselineAxisLaunchTest.sol"; + +// Axis +import {BALwithAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithAllowlist.sol"; + +contract BaselineAllowlistTest is BaselineAxisLaunchTest { + uint256 internal constant _BUYER_LIMIT = 5e18; + + // ========== MODIFIERS ========== // + + modifier givenCallbackIsCreated() override { + // Get the salt + bytes memory args = + abi.encode(address(_auctionHouse), _BASELINE_KERNEL, _BASELINE_QUOTE_TOKEN, _OWNER); + bytes32 salt = _getTestSalt("BaselineAllowlist", type(BALwithAllowlist).creationCode, args); + + // Required for CREATE2 address to work correctly. doesn't do anything in a test + // Source: https://github.com/foundry-rs/foundry/issues/6402 + vm.startBroadcast(); + _dtl = new BALwithAllowlist{salt: salt}( + address(_auctionHouse), _BASELINE_KERNEL, _BASELINE_QUOTE_TOKEN, _OWNER + ); + vm.stopBroadcast(); + + _dtlAddress = address(_dtl); + + // Call configureDependencies to set everything that's needed + _mockBaselineGetModuleForKeycode(); + _dtl.configureDependencies(); + _; + } + + modifier givenAllowlistParams(bytes32 merkleRoot_) { + _createData.allowlistParams = abi.encode(merkleRoot_); + _; + } +} diff --git a/test/callbacks/liquidity/BaselineV2/Allowlist/onBid.t.sol b/test/callbacks/liquidity/BaselineV2/Allowlist/onBid.t.sol new file mode 100644 index 00000000..e381896f --- /dev/null +++ b/test/callbacks/liquidity/BaselineV2/Allowlist/onBid.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaselineAllowlistTest} from + "test/callbacks/liquidity/BaselineV2/Allowlist/BaselineAllowlistTest.sol"; + +import {BaseCallback} from "src/callbacks/BaseCallback.sol"; +import {BALwithAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithAllowlist.sol"; + +contract BaselineAllowlistOnBidTest is BaselineAllowlistTest { + // Use the @openzeppelin/merkle-tree package or the scripts in axis-utils to generate the merkle tree + + // Values: + // 0x0000000000000000000000000000000000000004 + // 0x0000000000000000000000000000000000000005 + bytes32 internal constant _MERKLE_ROOT = + 0xc92348ba87c65979cc4f264810321a35efa64e795075908af2c507a22d4da472; + bytes32 internal constant _BUYER_MERKLE_PROOF = + 0x16db2e4b9f8dc120de98f8491964203ba76de27b27b29c2d25f85a325cd37477; + bytes32 internal constant _NOT_SELLER_MERKLE_PROOF = + 0xc167b0e3c82238f4f2d1a50a8b3a44f96311d77b148c30dc0ef863e1a060dcb6; + + bytes32[] internal _proof; + + uint64 internal constant _BID_ID = 1; + + // ========== MODIFIER ========== // + + modifier givenMerkleProof(bytes32 merkleProof_) { + bytes32[] memory proof = new bytes32[](1); + proof[0] = merkleProof_; + + _proof = proof; + _; + } + + function _onBid(uint256 bidAmount_) internal { + // Call the callback + vm.prank(address(_auctionHouse)); + _dtl.onBid(_lotId, _BID_ID, _BUYER, bidAmount_, abi.encode(_proof)); + } + + // ========== TESTS ========== // + + // [X] when the allowlist parameters are in an incorrect format + // [X] it reverts + // [X] when the merkle proof is invalid + // [X] it reverts + // [X] when the buyer is not in the merkle tree + // [X] it reverts + // [X] it succeeds + + function test_parametersInvalid_reverts() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + givenOnCreate + { + // Expect revert + vm.expectRevert(); + + // Call the callback with an invalid parameter format + vm.prank(address(_auctionHouse)); + _dtl.onBid(_lotId, _BID_ID, _BUYER, 5e18, abi.encode(uint256(20), bytes("something"))); + } + + function test_merkleProofInvalid_reverts() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + givenOnCreate + givenMerkleProof(_NOT_SELLER_MERKLE_PROOF) + { + // Expect revert + bytes memory err = abi.encodeWithSelector(BaseCallback.Callback_NotAuthorized.selector); + vm.expectRevert(err); + + // Call the callback with an invalid merkle proof + _onBid(5e18); + } + + function test_buyerNotInMerkleTree_reverts() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + givenOnCreate + givenMerkleProof(_BUYER_MERKLE_PROOF) + { + // Expect revert + bytes memory err = abi.encodeWithSelector(BaseCallback.Callback_NotAuthorized.selector); + vm.expectRevert(err); + + // Call the callback + vm.prank(address(_auctionHouse)); + _dtl.onBid(_lotId, _BID_ID, address(0x55), 5e18, abi.encode(_proof)); + } + + function test_success(uint256 bidAmount_) + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + givenOnCreate + givenMerkleProof(_BUYER_MERKLE_PROOF) + { + // Call the callback + _onBid(bidAmount_); + + // Does not revert + } +} diff --git a/test/callbacks/liquidity/BaselineV2/Allowlist/onCreate.t.sol b/test/callbacks/liquidity/BaselineV2/Allowlist/onCreate.t.sol new file mode 100644 index 00000000..f332d6fe --- /dev/null +++ b/test/callbacks/liquidity/BaselineV2/Allowlist/onCreate.t.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaselineAllowlistTest} from + "test/callbacks/liquidity/BaselineV2/Allowlist/BaselineAllowlistTest.sol"; + +import {BaseCallback} from "src/callbacks/BaseCallback.sol"; +import {BALwithAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithAllowlist.sol"; + +contract BaselineAllowlistOnCreateTest is BaselineAllowlistTest { + /// @dev This doesn't need to be valid at the moment + bytes32 internal constant _MERKLE_ROOT = + 0x1234567890123456789012345678901234567890123456789012345678901234; + + // ========== TESTS ========== // + + // [X] when the allowlist parameters are in an incorrect format + // [X] it reverts + // [X] it decodes and stores the merkle root + + function test_allowlistParamsIncorrect_reverts() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + { + // Set the allowlist parameters to be an incorrect format + _createData.allowlistParams = abi.encode(uint256(20), bytes32("hello"), uint256(10)); + + // Expect revert + bytes memory err = abi.encodeWithSelector(BaseCallback.Callback_InvalidParams.selector); + vm.expectRevert(err); + + // Call the callback + _onCreate(); + } + + function test_success() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + { + // Call the callback + _onCreate(); + + // Check the merkle root is stored + assertEq(BALwithAllowlist(address(_dtl)).merkleRoot(), _MERKLE_ROOT, "merkle root"); + } +} diff --git a/test/callbacks/liquidity/BaselineV2/Allowlist/setMerkleRoot.t.sol b/test/callbacks/liquidity/BaselineV2/Allowlist/setMerkleRoot.t.sol new file mode 100644 index 00000000..51164d03 --- /dev/null +++ b/test/callbacks/liquidity/BaselineV2/Allowlist/setMerkleRoot.t.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import {BaselineAllowlistTest} from + "test/callbacks/liquidity/BaselineV2/Allowlist/BaselineAllowlistTest.sol"; + +import {BaseCallback} from "src/callbacks/BaseCallback.sol"; +import {BALwithAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithAllowlist.sol"; + +contract BaselineAllowlistSetMerkleRootTest is BaselineAllowlistTest { + /// @dev This doesn't need to be valid at the moment + bytes32 internal constant _MERKLE_ROOT = + 0x1234567890123456789012345678901234567890123456789012345678901234; + bytes32 internal constant _NEW_MERKLE_ROOT = + 0x1234567890123456789012345678901234567890123456789012345678901234; + + function _setMerkleRoot() internal { + vm.prank(_OWNER); + BALwithAllowlist(address(_dtl)).setMerkleRoot(_NEW_MERKLE_ROOT); + } + + // ========== TESTS ========== // + + // [X] when the caller is not the owner + // [X] it reverts + // [X] when the auction has not been registered + // [X] it reverts + // [X] when the auction has been completed + // [X] it reverts + // [X] the merkle root is updated and an event is emitted + + function test_notOwner_reverts() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + givenOnCreate + { + // Expect revert + vm.expectRevert("UNAUTHORIZED"); + + // Call the callback + BALwithAllowlist(address(_dtl)).setMerkleRoot(_NEW_MERKLE_ROOT); + } + + function test_auctionNotRegistered_reverts() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + { + // Expect revert + bytes memory err = abi.encodeWithSelector(BALwithAllowlist.Callback_InvalidState.selector); + vm.expectRevert(err); + + // Call the callback + _setMerkleRoot(); + } + + function test_auctionCompleted_reverts() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + givenOnCreate + givenAddressHasQuoteTokenBalance(_dtlAddress, _PROCEEDS_AMOUNT) + givenAddressHasBaseTokenBalance(_dtlAddress, _REFUND_AMOUNT) + givenOnSettle + { + // Expect revert + bytes memory err = abi.encodeWithSelector(BALwithAllowlist.Callback_InvalidState.selector); + vm.expectRevert(err); + + // Call the callback + _setMerkleRoot(); + } + + function test_success() + public + givenBPoolIsCreated + givenCallbackIsCreated + givenAuctionIsCreated + givenAllowlistParams(_MERKLE_ROOT) + givenOnCreate + { + // Call the callback + _setMerkleRoot(); + + // Check the merkle root is updated + assertEq(BALwithAllowlist(address(_dtl)).merkleRoot(), _NEW_MERKLE_ROOT, "merkle root"); + } +} diff --git a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/BaselineCappedAllowlistTest.sol b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/BaselineCappedAllowlistTest.sol index 4a7add7b..04383e9e 100644 --- a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/BaselineCappedAllowlistTest.sol +++ b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/BaselineCappedAllowlistTest.sol @@ -6,8 +6,7 @@ import {BaselineAxisLaunchTest} from "test/callbacks/liquidity/BaselineV2/BaselineAxisLaunchTest.sol"; // Axis -import {BALwithCappedAllowlist} from - "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; +import {BALwithCappedAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; contract BaselineCappedAllowlistTest is BaselineAxisLaunchTest { uint256 internal constant _BUYER_LIMIT = 5e18; @@ -18,9 +17,8 @@ contract BaselineCappedAllowlistTest is BaselineAxisLaunchTest { // Get the salt bytes memory args = abi.encode(address(_auctionHouse), _BASELINE_KERNEL, _BASELINE_QUOTE_TOKEN, _OWNER); - bytes32 salt = _getTestSalt( - "BaselineCappedAllowlist", type(BALwithCappedAllowlist).creationCode, args - ); + bytes32 salt = + _getTestSalt("BaselineCappedAllowlist", type(BALwithCappedAllowlist).creationCode, args); // Required for CREATE2 address to work correctly. doesn't do anything in a test // Source: https://github.com/foundry-rs/foundry/issues/6402 diff --git a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onBid.t.sol b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onBid.t.sol index 1b5d0f2b..feb83943 100644 --- a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onBid.t.sol +++ b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onBid.t.sol @@ -5,15 +5,14 @@ import {BaselineCappedAllowlistTest} from "test/callbacks/liquidity/BaselineV2/CappedAllowlist/BaselineCappedAllowlistTest.sol"; import {BaseCallback} from "src/callbacks/BaseCallback.sol"; -import {BALwithCappedAllowlist} from - "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; +import {BALwithCappedAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; contract BaselineCappedAllowlistOnBidTest is BaselineCappedAllowlistTest { // Use the @openzeppelin/merkle-tree package or the scripts in axis-utils to generate the merkle tree // Values: - // 0x0000000000000000000000000000000000000004, 5e18 - // 0x0000000000000000000000000000000000000020, 0 + // 0x0000000000000000000000000000000000000004 + // 0x0000000000000000000000000000000000000005 bytes32 internal constant _MERKLE_ROOT = 0xc92348ba87c65979cc4f264810321a35efa64e795075908af2c507a22d4da472; bytes32 internal constant _BUYER_MERKLE_PROOF = @@ -22,7 +21,6 @@ contract BaselineCappedAllowlistOnBidTest is BaselineCappedAllowlistTest { 0xc167b0e3c82238f4f2d1a50a8b3a44f96311d77b148c30dc0ef863e1a060dcb6; bytes32[] internal _proof; - uint256 internal _allocatedAmount; uint64 internal constant _BID_ID = 1; @@ -108,7 +106,7 @@ contract BaselineCappedAllowlistOnBidTest is BaselineCappedAllowlistTest { // Call the callback vm.prank(address(_auctionHouse)); - _dtl.onBid(_lotId, _BID_ID, address(0x55), 5e18, abi.encode(_proof, _allocatedAmount)); + _dtl.onBid(_lotId, _BID_ID, address(0x55), 5e18, abi.encode(_proof)); } function test_buyerLimitSpent_reverts() diff --git a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onCreate.t.sol b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onCreate.t.sol index fb6de255..426e0066 100644 --- a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onCreate.t.sol +++ b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/onCreate.t.sol @@ -5,8 +5,7 @@ import {BaselineCappedAllowlistTest} from "test/callbacks/liquidity/BaselineV2/CappedAllowlist/BaselineCappedAllowlistTest.sol"; import {BaseCallback} from "src/callbacks/BaseCallback.sol"; -import {BALwithCappedAllowlist} from - "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; +import {BALwithCappedAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; contract BaselineCappedAllowlistOnCreateTest is BaselineCappedAllowlistTest { /// @dev This doesn't need to be valid at the moment diff --git a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/setMerkleRoot.t.sol b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/setMerkleRoot.t.sol index 990659a7..03e82dfb 100644 --- a/test/callbacks/liquidity/BaselineV2/CappedAllowlist/setMerkleRoot.t.sol +++ b/test/callbacks/liquidity/BaselineV2/CappedAllowlist/setMerkleRoot.t.sol @@ -5,8 +5,7 @@ import {BaselineCappedAllowlistTest} from "test/callbacks/liquidity/BaselineV2/CappedAllowlist/BaselineCappedAllowlistTest.sol"; import {BaseCallback} from "src/callbacks/BaseCallback.sol"; -import {BALwithCappedAllowlist} from - "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; +import {BALwithCappedAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithCappedAllowlist.sol"; import {BALwithAllowlist} from "src/callbacks/liquidity/BaselineV2/BALwithAllowlist.sol"; contract BaselineCappedAllowlistSetMerkleRootTest is BaselineCappedAllowlistTest { @@ -54,8 +53,7 @@ contract BaselineCappedAllowlistSetMerkleRootTest is BaselineCappedAllowlistTest givenAllowlistParams(_MERKLE_ROOT, _BUYER_LIMIT) { // Expect revert - bytes memory err = - abi.encodeWithSelector(BALwithAllowlist.Callback_InvalidState.selector); + bytes memory err = abi.encodeWithSelector(BALwithAllowlist.Callback_InvalidState.selector); vm.expectRevert(err); // Call the callback @@ -74,8 +72,7 @@ contract BaselineCappedAllowlistSetMerkleRootTest is BaselineCappedAllowlistTest givenOnSettle { // Expect revert - bytes memory err = - abi.encodeWithSelector(BALwithAllowlist.Callback_InvalidState.selector); + bytes memory err = abi.encodeWithSelector(BALwithAllowlist.Callback_InvalidState.selector); vm.expectRevert(err); // Call the callback