diff --git a/foundry.toml b/foundry.toml index 79e9125..a425435 100644 --- a/foundry.toml +++ b/foundry.toml @@ -8,23 +8,18 @@ ast = true build_info = true extra_output = ["storageLayout"] unchecked_cheatcode_artifacts = true - -[profile.deploy] -optimizer = true -optimizer_runs = 999999 +evm_version="cancun" [rpc_endpoints] unichain_sepolia = "https://sepolia.unichain.org" arbitrum_sepolia = "https://sepolia-rollup.arbitrum.io/rpc" +base_sepolia = "https://sepolia.base.org/" [etherscan] unichain_sepolia = { key = "${ETHERSCAN_API_KEY}" } arbitrum_sepolia = { key = "${ETHERSCAN_API_KEY}" } +basescan_sepolia = { key = "${BASESCAN_API_KEY}" } [fmt] sort_imports = true wrap_comments = true - -remappings = [ - "@openzeppelin/contracts/security/ReentrancyGuard.sol=lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol", -] diff --git a/test/BicTokenPaymaster/BicTokenPaymasterTestBase.sol b/test/BicTokenPaymaster/BicTokenPaymasterTestBase.sol index 9a764ed..b2185ef 100644 --- a/test/BicTokenPaymaster/BicTokenPaymasterTestBase.sol +++ b/test/BicTokenPaymaster/BicTokenPaymasterTestBase.sol @@ -69,17 +69,6 @@ contract BicTokenPaymasterTestBase is Test { return uniswapV2Pair; } - // Offset of _accumulatedLF in the BicStorage.Data struct - uint256 private constant ACCUMULATED_LF_OFFSET = 6; - function getAccumulatedLF() public view returns (uint256) { - return uint256( - vm.load( - address(bic), - bytes32(uint256(BicTokenPaymasterStorageLocation) + ACCUMULATED_LF_OFFSET) - ) - ); - } - // Offset of _LFReduction in the BicStorage.Data struct uint256 private constant LF_REDUCTION_OFFSET = 1; function getLFReduction() public view returns (uint256) { @@ -121,6 +110,92 @@ contract BicTokenPaymasterTestBase is Test { ); } + uint256 private constant MIN_SWAP_BACK_AMOUNT_OFFSET = 5; + function getMinSwapBackAmount() public view returns (uint256) { + return uint256( + vm.load( + address(bic), + bytes32(uint256(BicTokenPaymasterStorageLocation) + MIN_SWAP_BACK_AMOUNT_OFFSET) + ) + ); + } + + uint256 private constant ACCUMULATED_LF_OFFSET = 6; + function getAccumulatedLF() public view returns (uint256) { + return uint256( + vm.load( + address(bic), + bytes32(uint256(BicTokenPaymasterStorageLocation) + ACCUMULATED_LF_OFFSET) + ) + ); + } + + uint256 private constant ROUTER_N_BOOL_FLAGS_OFFSET = 9; + function getRouterNBoolFlags() public view returns (address router, bool prePublic, bool swapBackEnable, bool swapping) { + bytes32 data = vm.load( + address(bic), + bytes32(uint256(BicTokenPaymasterStorageLocation) + ROUTER_N_BOOL_FLAGS_OFFSET) + ); +// bytes calldata dataCalldata = abi.encodePacked(data); +// console.logBytes32(data); +// router = address(uint160(bytes20(dataCalldata[13:]))); +// console.log("router: ", router); +// prePublic = uint8(bytes1(data[12])) == 1; +// console.log("prePublic: ", prePublic); +// swapBackEnable = uint8(bytes1(data[11])) == 1; +// console.log("swapBackEnable: ", swapBackEnable); +// swapping = uint8(bytes1(data[10])) == 1; +// console.log("swapping: ", swapping); + assembly { + // Extract the 3 boolean flags from the 12th byte + let flags := shr(160, data) // Shift 253 bits to the right (256 - 3 = 253) + prePublic := and(flags, 8) // Extract the least significant bit + swapBackEnable := and(shr(8, flags), 8) // Extract the second bit + swapping := and(shr(16, flags), 8) // Extract the third bit + + // Extract the last 20 bytes (160 bits) for the router address + router := and(data, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +// router := shr(96, data) +// prePublic := shr(104, data) +// swapBackEnable := shr(112, data) +// swapping := shr(120, data) + } + console.log("router: ", router); + console.log("prePublic: ", prePublic); + console.log("swapBackEnable: ", swapBackEnable); + console.log("swapping: ", swapping); + } + + uint256 private constant LIQUIDITY_TREASURY_OFFSET = 7; + function getLiquidityTreasury() public view returns (address) { + return address( + uint160( + uint256( + vm.load( + address(bic), + bytes32(uint256(BicTokenPaymasterStorageLocation) + LIQUIDITY_TREASURY_OFFSET) + ) + ) + ) + ); + } + + uint256 private constant IS_EXCLUDED_OFFSET = 13; + function isExcluded(address addr) public view returns (bool) { + return uint256(vm.load( + address(bic), + keccak256(abi.encode(addr, bytes32(uint256(BicTokenPaymasterStorageLocation) + IS_EXCLUDED_OFFSET))) + )) == 1; + } + + uint256 private constant POOL_OFFSET = 14; + function isPool(address addr) public view returns (bool) { + return uint256(vm.load( + address(bic), + keccak256(abi.encode(addr, bytes32(uint256(BicTokenPaymasterStorageLocation) + POOL_OFFSET))) + )) == 1; + } + uint256 private constant BLOCKED_OFFSET = 15; function isBlocked(address addr) public view returns (bool) { uint256 slotMapping = uint256(BicTokenPaymasterStorageLocation) + BLOCKED_OFFSET; diff --git a/test/BicTokenPaymaster/smart-account/MultiSinger.t.sol b/test/BicTokenPaymaster/smart-account/MultiSinger.t.sol new file mode 100644 index 0000000..e5d4e17 --- /dev/null +++ b/test/BicTokenPaymaster/smart-account/MultiSinger.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + +import "../BicTokenPaymasterTestBase.sol"; + +contract TestMultiSinger is BicTokenPaymasterTestBase { + address public random_signer = vm.addr(0x575); + function setUp() public virtual override { + super.setUp(); + } + + function test_addAndRemoveSigner() public { + assertEq(bic.signers(owner), true); + assertEq(bic.signers(dev), true); + assertEq(bic.signers(random_signer), false); + vm.startPrank(owner); + bic.addSigner(random_signer); + assertEq(bic.signers(random_signer), true); + bic.removeSigner(random_signer); + assertEq(bic.signers(random_signer), false); + vm.stopPrank(); + } +} \ No newline at end of file diff --git a/test/BicTokenPaymaster/smart-account/Paymaster.t.sol b/test/BicTokenPaymaster/smart-account/Paymaster.t.sol index 25c8187..06be2ce 100644 --- a/test/BicTokenPaymaster/smart-account/Paymaster.t.sol +++ b/test/BicTokenPaymaster/smart-account/Paymaster.t.sol @@ -16,8 +16,6 @@ contract TestPaymaster is BicTokenPaymasterTestBase { address public random_executor = address(0xeee); -// error FailedOp(uint256 opIndex, string reason); - function setUp() public virtual override { super.setUp(); smart_account_factory = new SimpleAccountFactory(entrypoint); @@ -191,6 +189,7 @@ contract TestPaymaster is BicTokenPaymasterTestBase { entrypoint.handleOps(userOps, payable(random_executor)); assertEq(isContract(user1AccountAddress), false); } + function test_createOracleUserOp_SuccessWithFixedFeeOracleAndFactory() public { bytes memory initCallData = abi.encodeWithSignature("createAccount(address,uint256)", user1, 0); bytes memory initCode = abi.encodePacked(abi.encodePacked(address(smart_account_factory)), initCallData); diff --git a/test/BicTokenPaymaster/swap/BicUniswapPublic.t.sol b/test/BicTokenPaymaster/swap/BicUniswapPublic.t.sol index 0549f10..9f87686 100644 --- a/test/BicTokenPaymaster/swap/BicUniswapPublic.t.sol +++ b/test/BicTokenPaymaster/swap/BicUniswapPublic.t.sol @@ -448,6 +448,7 @@ contract BicForkUniswapV2 is BicTokenPaymasterTestBase { uint256 currentLF = bic.getCurrentLF(); uint256 estLF = simulateLF(LFStartTime, currentTime); + uint256 deadline = currentTime + 60; // Check LF conditions assertEq(currentLF, estLF, "Current LF should match estimated LF"); @@ -480,7 +481,7 @@ contract BicForkUniswapV2 is BicTokenPaymasterTestBase { 0, // min amount out swapPath, user1, - currentTime + 60 + deadline ); vm.stopPrank(); @@ -515,7 +516,7 @@ contract BicForkUniswapV2 is BicTokenPaymasterTestBase { 0, swapPath, user2, - currentTime + 60 + deadline ); vm.stopPrank(); uint256 LFBalanceAfter = pair.balanceOf(owner); diff --git a/test/BicTokenPaymaster/swap/LiquidityFee.t.sol b/test/BicTokenPaymaster/swap/LiquidityFee.t.sol index 76bbc90..5be4a8d 100644 --- a/test/BicTokenPaymaster/swap/LiquidityFee.t.sol +++ b/test/BicTokenPaymaster/swap/LiquidityFee.t.sol @@ -35,4 +35,100 @@ contract LiquidityFee is BicTokenPaymasterTestBase { assertEq(uniswapV2Factory.feeToSetter(), address(54321)); } + function test_setLiquidityTreasuryUpdated() public { + address newTreasury = vm.addr(0x00001); + vm.prank(owner); + bic.setLiquidityTreasury(newTreasury); + assertEq(newTreasury, getLiquidityTreasury()); + } + + function test_setLiquidityFeeUpdated() public { + uint256 newMinFee = 1000; + uint256 newMaxFee = 2000; + vm.prank(owner); + bic.setLiquidityFee(newMinFee, newMaxFee); + assertEq(newMinFee, getMinLF()); + assertEq(newMaxFee, getMaxLF()); + } + + function test_setLFReduction() public { + uint256 newReduction = 1000; + vm.prank(owner); + bic.setLFReduction(newReduction); + assertEq(newReduction, getLFReduction()); + } + + function test_setLFPeriod() public { + uint256 newPeriod = 1000; + vm.prank(owner); + bic.setLFPeriod(newPeriod); + assertEq(newPeriod, getLFPeriod()); + } + + function test_setSwapBackEnabled() public { + (, , bool swapBackEnabled, ) = getRouterNBoolFlags(); + assertEq(true, swapBackEnabled); + vm.prank(owner); + bic.setSwapBackEnabled(false); + (, bool t1, bool swapBackEnabled2, bool t2) = getRouterNBoolFlags(); + assertEq(false, swapBackEnabled2); + } + + function test_setMinSwapBackAmount() public { + uint256 newMinSwapBackAmount = 1000; + vm.prank(owner); + bic.setMinSwapBackAmount(newMinSwapBackAmount); + assertEq(newMinSwapBackAmount, getMinSwapBackAmount()); + } + + function test_setLiquidityTreasury() public { + address newTreasury = vm.addr(0x00001); + vm.prank(owner); + bic.setLiquidityTreasury(newTreasury); + assertEq(newTreasury, getLiquidityTreasury()); + } + + function test_setPool() public { + vm.prank(owner); + bic.setPool(bicUniswapPair, true); + assertEq(true, isPool(bicUniswapPair)); + } + + function test_setBulkExcluded() public { + address[] memory excluded = new address[](2); + excluded[0] = vm.addr(0x00001); + excluded[1] = vm.addr(0x00002); + vm.prank(owner); + bic.bulkExcluded(excluded, true); + assertEq(true, isExcluded(excluded[0])); + assertEq(true, isExcluded(excluded[1])); + } + + function test_pause() public { + assertEq(false, bic.paused()); + vm.prank(owner); + bic.pause(); + assertEq(true, bic.paused()); + vm.prank(owner); + bic.unpause(); + assertEq(false, bic.paused()); + } + + function test_withdrawStuckTokens() public { + address toAddress = vm.addr(0x10001); + uint256 amount = 1000; + vm.prank(owner); + bic.transfer(address(bic), amount); + assertEq(amount, bic.balanceOf(address(bic))); + vm.deal(address(bic), amount); + assertEq(amount, address(bic).balance); + vm.prank(owner); + bic.withdrawStuckToken(address(bic),toAddress,amount); + assertEq(amount, bic.balanceOf(toAddress)); + vm.prank(owner); + bic.withdrawStuckToken(address(0),toAddress,amount); + assertEq(amount, address(toAddress).balance); + } + + } \ No newline at end of file diff --git a/test/BicTokenPaymaster/utils/Block.t.sol b/test/BicTokenPaymaster/utils/Block.t.sol index 9d2e615..811b81a 100644 --- a/test/BicTokenPaymaster/utils/Block.t.sol +++ b/test/BicTokenPaymaster/utils/Block.t.sol @@ -1,3 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.23; + import {BicTokenPaymasterTestBase} from "../BicTokenPaymasterTestBase.sol"; contract BlockTest is BicTokenPaymasterTestBase {