From 095503b84767d9230fc7bf80e3c1080fa2fa725d Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:41:47 +0800 Subject: [PATCH 1/5] feat: Add settleAndRefund --- ...oolManagerTest#testBurnNativeCurrency.snap | 2 +- ...BinPoolManagerTest#testGasBurnHalfBin.snap | 2 +- ...inPoolManagerTest#testGasBurnNineBins.snap | 2 +- .../BinPoolManagerTest#testGasBurnOneBin.snap | 2 +- .../BinPoolManagerTest#testGasDonate.snap | 2 +- ...nPoolManagerTest#testGasMintNneBins-1.snap | 2 +- ...nPoolManagerTest#testGasMintNneBins-2.snap | 2 +- ...inPoolManagerTest#testGasMintOneBin-1.snap | 2 +- ...inPoolManagerTest#testGasMintOneBin-2.snap | 2 +- ...olManagerTest#testGasSwapMultipleBins.snap | 2 +- ...nagerTest#testGasSwapOverBigBinIdGate.snap | 2 +- ...nPoolManagerTest#testGasSwapSingleBin.snap | 2 +- ...oolManagerTest#testMintNativeCurrency.snap | 2 +- .../BinPoolManagerTest#testNoOpGas_Burn.snap | 2 +- ...BinPoolManagerTest#testNoOpGas_Donate.snap | 2 +- .../BinPoolManagerTest#testNoOpGas_Mint.snap | 2 +- .../BinPoolManagerTest#testNoOpGas_Swap.snap | 2 +- ...oolManagerTest#addLiquidity_fromEmpty.snap | 2 +- ...ManagerTest#addLiquidity_fromNonEmpty.snap | 2 +- ...lManagerTest#addLiquidity_nativeToken.snap | 2 +- .../CLPoolManagerTest#donateBothTokens.snap | 2 +- .../CLPoolManagerTest#gasDonateOneToken.snap | 2 +- ...anagerTest#removeLiquidity_toNonEmpty.snap | 2 +- ...PoolManagerTest#swap_againstLiquidity.snap | 2 +- ...gerTest#swap_leaveSurplusTokenInVault.snap | 2 +- ...oolManagerTest#swap_runOutOfLiquidity.snap | 2 +- .../CLPoolManagerTest#swap_simple.snap | 2 +- ...nagerTest#swap_useSurplusTokenAsInput.snap | 2 +- .../CLPoolManagerTest#swap_withHooks.snap | 2 +- .../CLPoolManagerTest#swap_withNative.snap | 2 +- ...CLPoolManagerTest#testNoOp_gas_Donate.snap | 2 +- ...nagerTest#testNoOp_gas_ModifyPosition.snap | 2 +- .../CLPoolManagerTest#testNoOp_gas_Swap.snap | 2 +- .forge-snapshots/VaultTest#Vault.snap | 2 +- ...VaultTest#lockSettledWhenAddLiquidity.snap | 1 + .../VaultTest#lockSettledWhenFlashloan.snap | 2 +- ...VaultTest#lockSettledWhenMultiHopSwap.snap | 2 +- .../VaultTest#lockSettledWhenSwap.snap | 2 +- .../VaultTest#registerPoolManager.snap | 2 +- .forge-snapshots/VaultTest#testLock_NoOp.snap | 2 +- ...testSettleAndRefund_WithErc20Transfer.snap | 1 + ...tSettleAndRefund_WithoutErc20Transfer.snap | 1 + src/Vault.sol | 18 +++++++++- src/interfaces/IVault.sol | 3 ++ test/vault/FakePoolManagerRouter.sol | 3 ++ test/vault/Vault.t.sol | 34 ++++++++++++++++++- test/vault/VaultInvariant.t.sol | 28 ++++++++++++++- 47 files changed, 125 insertions(+), 42 deletions(-) create mode 100644 .forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap create mode 100644 .forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap create mode 100644 .forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap diff --git a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap index ea4b1578..b6a0d9ab 100644 --- a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap @@ -1 +1 @@ -92310 \ No newline at end of file +92245 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap index 6f7475df..e0a09995 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap @@ -1 +1 @@ -67502 \ No newline at end of file +67437 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap index b98ae40d..d570894d 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap @@ -1 +1 @@ -151057 \ No newline at end of file +150992 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap index 5c0a7311..33434dff 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap @@ -1 +1 @@ -68681 \ No newline at end of file +68616 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap b/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap index 43d2d930..760655c0 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap @@ -1 +1 @@ -53973 \ No newline at end of file +53952 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap index 61b20b76..fcedea97 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap @@ -1 +1 @@ -968068 \ No newline at end of file +968047 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap index 49498dc8..606a4052 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap @@ -1 +1 @@ -121582 \ No newline at end of file +121561 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap index 265f873c..08f6d723 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap @@ -1 +1 @@ -337258 \ No newline at end of file +337237 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap index 8fe11fbd..46204462 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap @@ -1 +1 @@ -56319 \ No newline at end of file +56298 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap b/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap index 1a47e6c0..2013546b 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap @@ -1 +1 @@ -93083 \ No newline at end of file +93040 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap b/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap index 4a80de55..0ac0f030 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap @@ -1 +1 @@ -95068 \ No newline at end of file +95025 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap index cb9b82af..5752d2a0 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap @@ -1 +1 @@ -74512 \ No newline at end of file +74469 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap index 54bdfcb1..4a71833f 100644 --- a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap @@ -1 +1 @@ -318966 \ No newline at end of file +318945 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap index cde60315..644edbae 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap @@ -1 +1 @@ -41941 \ No newline at end of file +41876 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap index 7e2d8e03..f17589cd 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap @@ -1 +1 @@ -19558 \ No newline at end of file +19493 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap index edf5a379..78d7f8e8 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap @@ -1 +1 @@ -37410 \ No newline at end of file +37345 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap index bed35a26..bbdca60d 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap @@ -1 +1 @@ -22764 \ No newline at end of file +22699 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap index 49f1036e..a3b6d98b 100644 --- a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap +++ b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap @@ -1 +1 @@ -348473 \ No newline at end of file +348452 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap index ab1b307f..4bbcfa2c 100644 --- a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap +++ b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap @@ -1 +1 @@ -61021 \ No newline at end of file +61000 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap b/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap index c84788c7..9d0018b5 100644 --- a/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap +++ b/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap @@ -1 +1 @@ -241433 \ No newline at end of file +241390 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap b/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap index ac8527f0..ff632f9d 100644 --- a/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap +++ b/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap @@ -1 +1 @@ -84159 \ No newline at end of file +84138 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap b/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap index a0f8fb32..ad879fda 100644 --- a/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap +++ b/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap @@ -1 +1 @@ -53488 \ No newline at end of file +53445 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap b/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap index d31d5b07..beda75cb 100644 --- a/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap +++ b/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap @@ -1 +1 @@ -43387 \ No newline at end of file +43322 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap b/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap index ad044164..81cd8b6b 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap @@ -1 +1 @@ -56488 \ No newline at end of file +56445 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap b/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap index cff0aa8a..5a1b0a20 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap @@ -1 +1 @@ -104597 \ No newline at end of file +104554 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap b/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap index 1168907c..4475c1ca 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap @@ -1 +1 @@ -25044312 \ No newline at end of file +25044269 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_simple.snap b/.forge-snapshots/CLPoolManagerTest#swap_simple.snap index 4dedc7ce..67c6dee8 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_simple.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_simple.snap @@ -1 +1 @@ -36401 \ No newline at end of file +36336 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap b/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap index e580758f..62871273 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap @@ -1 +1 @@ -103140 \ No newline at end of file +103030 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap b/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap index 610ccdf8..0fd73b02 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap @@ -1 +1 @@ -42051 \ No newline at end of file +41986 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap b/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap index 9cc8594e..0aecb1ad 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap @@ -1 +1 @@ -36404 \ No newline at end of file +36339 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap index 366744e2..7b7d760c 100644 --- a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap +++ b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap @@ -1 +1 @@ -19513 \ No newline at end of file +19448 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap index 3fdaecea..228723ef 100644 --- a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap +++ b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap @@ -1 +1 @@ -27680 \ No newline at end of file +27615 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap index 4eb79bea..9e1e60bf 100644 --- a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap +++ b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap @@ -1 +1 @@ -21962 \ No newline at end of file +21897 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#Vault.snap b/.forge-snapshots/VaultTest#Vault.snap index 5f9db2ba..cb8c98cd 100644 --- a/.forge-snapshots/VaultTest#Vault.snap +++ b/.forge-snapshots/VaultTest#Vault.snap @@ -1 +1 @@ -6762 \ No newline at end of file +7016 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap b/.forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap new file mode 100644 index 00000000..cbf29f3c --- /dev/null +++ b/.forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap @@ -0,0 +1 @@ +122519 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap b/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap index f583bc35..932d963e 100644 --- a/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap +++ b/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap @@ -1 +1 @@ -158832 \ No newline at end of file +158811 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap b/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap index 9638b220..37e2ed50 100644 --- a/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap +++ b/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap @@ -1 +1 @@ -47017 \ No newline at end of file +46974 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap b/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap index ccf5975c..e6f87cf8 100644 --- a/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap +++ b/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap @@ -1 +1 @@ -47016 \ No newline at end of file +46973 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#registerPoolManager.snap b/.forge-snapshots/VaultTest#registerPoolManager.snap index f8a88baa..67481fbe 100644 --- a/.forge-snapshots/VaultTest#registerPoolManager.snap +++ b/.forge-snapshots/VaultTest#registerPoolManager.snap @@ -1 +1 @@ -24484 \ No newline at end of file +24506 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testLock_NoOp.snap b/.forge-snapshots/VaultTest#testLock_NoOp.snap index 738d2bc9..60052106 100644 --- a/.forge-snapshots/VaultTest#testLock_NoOp.snap +++ b/.forge-snapshots/VaultTest#testLock_NoOp.snap @@ -1 +1 @@ -11502 \ No newline at end of file +11532 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap new file mode 100644 index 00000000..8aa8a574 --- /dev/null +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap @@ -0,0 +1 @@ +75609 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap new file mode 100644 index 00000000..8ac5cf77 --- /dev/null +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap @@ -0,0 +1 @@ +33010 \ No newline at end of file diff --git a/src/Vault.sol b/src/Vault.sol index eb64a9e3..cbf5386f 100644 --- a/src/Vault.sol +++ b/src/Vault.sol @@ -118,7 +118,7 @@ contract Vault is IVault, VaultToken, Ownable { } /// @inheritdoc IVault - function settle(Currency currency) external payable override isLocked returns (uint256 paid) { + function settle(Currency currency) public payable override isLocked returns (uint256 paid) { uint256 reservesBefore = reservesOfVault[currency]; reservesOfVault[currency] = currency.balanceOfSelf(); paid = reservesOfVault[currency] - reservesBefore; @@ -126,6 +126,22 @@ contract Vault is IVault, VaultToken, Ownable { SettlementGuard.accountDelta(msg.sender, currency, -(paid.toInt128())); } + function settleAndRefund(Currency currency) external payable isLocked returns (uint256 paid, uint256 refund) { + paid = settle(currency); + + int256 afterCurrencyDelta = SettlementGuard.getCurrencyDelta(msg.sender, currency); + if (afterCurrencyDelta < 0) { + /// If user currencyDelta is negative (vault owes owner) after settle: either user have overpaid + /// or someone have transfer token to the vault. + refund = uint256(-afterCurrencyDelta); + + /// thus refund msg.sender and update accountDelta + SettlementGuard.accountDelta(msg.sender, currency, refund.toInt128()); + reservesOfVault[currency] -= refund; + currency.transfer(msg.sender, refund); + } + } + /// @inheritdoc IVault function settleFor(Currency currency, address target, uint256 amount) external isLocked { /// @notice settle all outstanding debt if amount is 0 diff --git a/src/interfaces/IVault.sol b/src/interfaces/IVault.sol index faff5b2a..d69d943f 100644 --- a/src/interfaces/IVault.sol +++ b/src/interfaces/IVault.sol @@ -67,6 +67,9 @@ interface IVault is IVaultToken { /// @notice Called by the user to pay what is owed function settle(Currency token) external payable returns (uint256 paid); + /// @notice Called by the user to pay what is owed. If the payment is more than the debt, the surplus is refunded + function settleAndRefund(Currency token) external payable returns (uint256 paid, uint256 refund); + /// @notice move the delta from target to the msg.sender, only payment delta can be moved /// @param currency The currency to settle /// @param target The address whose delta will be updated diff --git a/test/vault/FakePoolManagerRouter.sol b/test/vault/FakePoolManagerRouter.sol index ab7584fa..ba3aefb7 100644 --- a/test/vault/FakePoolManagerRouter.sol +++ b/test/vault/FakePoolManagerRouter.sol @@ -128,6 +128,9 @@ contract FakePoolManagerRouter { // settle ETH vault.settle{value: 5 ether}(CurrencyLibrary.NATIVE); vault.take(CurrencyLibrary.NATIVE, address(this), 5 ether); + } else if (data[0] == 0x18) { + vault.settleAndRefund(poolKey.currency0); + vault.settleAndRefund(poolKey.currency1); } return ""; diff --git a/test/vault/Vault.t.sol b/test/vault/Vault.t.sol index bfd4e1b2..a8f334c8 100644 --- a/test/vault/Vault.t.sol +++ b/test/vault/Vault.t.sol @@ -173,6 +173,38 @@ contract VaultTest is Test, GasSnapshot { vault.lock(hex"02"); } + function testSettleAndRefund_WithErc20Transfer() public { + // simulate someone transferred token to vault + currency0.transfer(address(vault), 10 ether); + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + + // settle and refund + vm.prank(address(fakePoolManagerRouter)); + snapStart("VaultTest#testSettleAndRefund_WithErc20Transfer"); + vault.lock(hex"18"); + snapEnd(); + + // verify + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 10 ether); + assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + } + + function testSettleAndRefund_WithoutErc20Transfer() public { + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + + // settleAndRefund works even if there's no excess currency + vm.prank(address(fakePoolManagerRouter)); + snapStart("VaultTest#testSettleAndRefund_WithoutErc20Transfer"); + vault.lock(hex"18"); + snapEnd(); + + // verify + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + } + function testNotCorrectPoolManager() public { // router => vault.lock // vault.lock => periphery.lockAcquired @@ -208,7 +240,7 @@ contract VaultTest is Test, GasSnapshot { vm.prank(address(fakePoolManagerRouter)); snapStart("VaultTest#lockSettledWhenAddLiquidity"); vault.lock(hex"02"); - snapStart("end"); + snapEnd(); assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(vault)), 10 ether); assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(vault)), 10 ether); diff --git a/test/vault/VaultInvariant.t.sol b/test/vault/VaultInvariant.t.sol index 92cfbf8e..37ff8391 100644 --- a/test/vault/VaultInvariant.t.sol +++ b/test/vault/VaultInvariant.t.sol @@ -31,6 +31,7 @@ contract VaultPoolManager is Test { enum ActionType { Take, Settle, + SettleAndRefund, SettleFor, Mint, Burn @@ -84,6 +85,21 @@ contract VaultPoolManager is Test { vault.lock(abi.encode(Action(ActionType.Settle, uint128(amt0), uint128(amt1)))); } + /// @dev In settleAndRefund case, assume user add liquidity and paying to the vault + /// but theres another folk who minted extra token to the vault + function settleAndRefund(uint256 amt0, uint256 amt1, bool sendToVault) public { + amt0 = bound(amt0, 0, MAX_TOKEN_BALANCE - 1 ether); + amt1 = bound(amt1, 0, MAX_TOKEN_BALANCE - 1 ether); + + // someone send some token directly to vault + if (sendToVault) token0.mint(address(vault), 1 ether); + + // mint token to VaultPoolManager, so VaultPoolManager can pay to the vault + token0.mint(address(this), amt0); + token1.mint(address(this), amt1); + vault.lock(abi.encode(Action(ActionType.SettleAndRefund, uint128(amt0), uint128(amt1)))); + } + /// @dev In settleFor case, assume user is paying for hook function settleFor(uint256 amt0, uint256 amt1) public { amt0 = bound(amt0, 0, MAX_TOKEN_BALANCE); @@ -165,6 +181,15 @@ contract VaultPoolManager is Test { vault.settle(currency0); vault.settle(currency1); + } else if (action.actionType == ActionType.SettleAndRefund) { + BalanceDelta delta = toBalanceDelta(int128(action.amt0), int128(action.amt1)); + vault.accountPoolBalanceDelta(poolKey, delta, address(this)); + + token0.transfer(address(vault), action.amt0); + token1.transfer(address(vault), action.amt1); + + vault.settleAndRefund(currency0); + vault.settleAndRefund(currency1); } else if (action.actionType == ActionType.SettleFor) { // hook cash out the fee ahead BalanceDelta delta = toBalanceDelta(int128(action.amt0), int128(action.amt1)); @@ -212,13 +237,14 @@ contract VaultInvariant is Test, GasSnapshot { // Only call vaultPoolManager, otherwise all other contracts deployed in setUp will be called targetContract(address(vaultPoolManager)); - bytes4[] memory selectors = new bytes4[](6); + bytes4[] memory selectors = new bytes4[](7); selectors[0] = VaultPoolManager.take.selector; selectors[1] = VaultPoolManager.mint.selector; selectors[2] = VaultPoolManager.settle.selector; selectors[3] = VaultPoolManager.burn.selector; selectors[4] = VaultPoolManager.settleFor.selector; selectors[5] = VaultPoolManager.collectFee.selector; + selectors[6] = VaultPoolManager.settleAndRefund.selector; targetSelector(FuzzSelector({addr: address(vaultPoolManager), selectors: selectors})); } From 7cf771cf21d582255342c164a492bee234337975 Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:17:19 +0800 Subject: [PATCH 2/5] feat: Add to in parameter for settleAndRefund --- ...PoolManagerTest#testBurnNativeCurrency.snap | 2 +- .../BinPoolManagerTest#testGasBurnHalfBin.snap | 2 +- ...BinPoolManagerTest#testGasBurnNineBins.snap | 2 +- .../BinPoolManagerTest#testGasBurnOneBin.snap | 2 +- .../BinPoolManagerTest#testGasDonate.snap | 2 +- ...inPoolManagerTest#testGasMintNneBins-1.snap | 2 +- ...inPoolManagerTest#testGasMintNneBins-2.snap | 2 +- ...BinPoolManagerTest#testGasMintOneBin-1.snap | 2 +- ...BinPoolManagerTest#testGasMintOneBin-2.snap | 2 +- ...oolManagerTest#testGasSwapMultipleBins.snap | 2 +- ...anagerTest#testGasSwapOverBigBinIdGate.snap | 2 +- ...inPoolManagerTest#testGasSwapSingleBin.snap | 2 +- ...PoolManagerTest#testMintNativeCurrency.snap | 2 +- .../BinPoolManagerTest#testNoOpGas_Burn.snap | 2 +- .../BinPoolManagerTest#testNoOpGas_Donate.snap | 2 +- .../BinPoolManagerTest#testNoOpGas_Mint.snap | 2 +- .../BinPoolManagerTest#testNoOpGas_Swap.snap | 2 +- ...PoolManagerTest#addLiquidity_fromEmpty.snap | 2 +- ...lManagerTest#addLiquidity_fromNonEmpty.snap | 2 +- ...olManagerTest#addLiquidity_nativeToken.snap | 2 +- .../CLPoolManagerTest#donateBothTokens.snap | 2 +- .../CLPoolManagerTest#gasDonateOneToken.snap | 2 +- ...ManagerTest#removeLiquidity_toNonEmpty.snap | 2 +- ...LPoolManagerTest#swap_againstLiquidity.snap | 2 +- ...agerTest#swap_leaveSurplusTokenInVault.snap | 2 +- ...PoolManagerTest#swap_runOutOfLiquidity.snap | 2 +- .../CLPoolManagerTest#swap_simple.snap | 2 +- ...anagerTest#swap_useSurplusTokenAsInput.snap | 2 +- .../CLPoolManagerTest#swap_withHooks.snap | 2 +- .../CLPoolManagerTest#swap_withNative.snap | 2 +- .../CLPoolManagerTest#testNoOp_gas_Donate.snap | 2 +- ...anagerTest#testNoOp_gas_ModifyPosition.snap | 2 +- .../CLPoolManagerTest#testNoOp_gas_Swap.snap | 2 +- .forge-snapshots/VaultTest#Vault.snap | 2 +- .../VaultTest#lockSettledWhenAddLiquidity.snap | 2 +- .../VaultTest#lockSettledWhenFlashloan.snap | 2 +- .../VaultTest#lockSettledWhenMultiHopSwap.snap | 2 +- .../VaultTest#lockSettledWhenSwap.snap | 2 +- .forge-snapshots/VaultTest#testLock_NoOp.snap | 2 +- ...#testSettleAndRefund_WithErc20Transfer.snap | 2 +- ...stSettleAndRefund_WithoutErc20Transfer.snap | 2 +- src/Vault.sol | 9 +++++++-- src/interfaces/IVault.sol | 4 +++- test/vault/FakePoolManagerRouter.sol | 6 ++++-- test/vault/Vault.t.sol | 18 +++++++++++------- test/vault/VaultInvariant.t.sol | 4 ++-- 46 files changed, 68 insertions(+), 55 deletions(-) diff --git a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap index b6a0d9ab..ea4b1578 100644 --- a/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testBurnNativeCurrency.snap @@ -1 +1 @@ -92245 \ No newline at end of file +92310 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap index e0a09995..6f7475df 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnHalfBin.snap @@ -1 +1 @@ -67437 \ No newline at end of file +67502 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap index d570894d..b98ae40d 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnNineBins.snap @@ -1 +1 @@ -150992 \ No newline at end of file +151057 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap index 33434dff..5c0a7311 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasBurnOneBin.snap @@ -1 +1 @@ -68616 \ No newline at end of file +68681 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap b/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap index 760655c0..43d2d930 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasDonate.snap @@ -1 +1 @@ -53952 \ No newline at end of file +53973 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap index fcedea97..61b20b76 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-1.snap @@ -1 +1 @@ -968047 \ No newline at end of file +968068 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap index 606a4052..49498dc8 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintNneBins-2.snap @@ -1 +1 @@ -121561 \ No newline at end of file +121582 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap index 08f6d723..265f873c 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-1.snap @@ -1 +1 @@ -337237 \ No newline at end of file +337258 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap index 46204462..8fe11fbd 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasMintOneBin-2.snap @@ -1 +1 @@ -56298 \ No newline at end of file +56319 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap b/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap index 2013546b..1a47e6c0 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasSwapMultipleBins.snap @@ -1 +1 @@ -93040 \ No newline at end of file +93083 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap b/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap index 0ac0f030..4a80de55 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasSwapOverBigBinIdGate.snap @@ -1 +1 @@ -95025 \ No newline at end of file +95068 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap b/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap index 5752d2a0..cb9b82af 100644 --- a/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap +++ b/.forge-snapshots/BinPoolManagerTest#testGasSwapSingleBin.snap @@ -1 +1 @@ -74469 \ No newline at end of file +74512 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap index 4a71833f..54bdfcb1 100644 --- a/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap +++ b/.forge-snapshots/BinPoolManagerTest#testMintNativeCurrency.snap @@ -1 +1 @@ -318945 \ No newline at end of file +318966 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap index 644edbae..cde60315 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Burn.snap @@ -1 +1 @@ -41876 \ No newline at end of file +41941 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap index f17589cd..7e2d8e03 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Donate.snap @@ -1 +1 @@ -19493 \ No newline at end of file +19558 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap index 78d7f8e8..edf5a379 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Mint.snap @@ -1 +1 @@ -37345 \ No newline at end of file +37410 \ No newline at end of file diff --git a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap index bbdca60d..bed35a26 100644 --- a/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap +++ b/.forge-snapshots/BinPoolManagerTest#testNoOpGas_Swap.snap @@ -1 +1 @@ -22699 \ No newline at end of file +22764 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap index a3b6d98b..49f1036e 100644 --- a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap +++ b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromEmpty.snap @@ -1 +1 @@ -348452 \ No newline at end of file +348473 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap index 4bbcfa2c..ab1b307f 100644 --- a/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap +++ b/.forge-snapshots/CLPoolManagerTest#addLiquidity_fromNonEmpty.snap @@ -1 +1 @@ -61000 \ No newline at end of file +61021 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap b/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap index 9d0018b5..c84788c7 100644 --- a/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap +++ b/.forge-snapshots/CLPoolManagerTest#addLiquidity_nativeToken.snap @@ -1 +1 @@ -241390 \ No newline at end of file +241433 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap b/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap index ff632f9d..ac8527f0 100644 --- a/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap +++ b/.forge-snapshots/CLPoolManagerTest#donateBothTokens.snap @@ -1 +1 @@ -84138 \ No newline at end of file +84159 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap b/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap index ad879fda..a0f8fb32 100644 --- a/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap +++ b/.forge-snapshots/CLPoolManagerTest#gasDonateOneToken.snap @@ -1 +1 @@ -53445 \ No newline at end of file +53488 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap b/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap index beda75cb..d31d5b07 100644 --- a/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap +++ b/.forge-snapshots/CLPoolManagerTest#removeLiquidity_toNonEmpty.snap @@ -1 +1 @@ -43322 \ No newline at end of file +43387 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap b/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap index 81cd8b6b..ad044164 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_againstLiquidity.snap @@ -1 +1 @@ -56445 \ No newline at end of file +56488 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap b/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap index 5a1b0a20..cff0aa8a 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_leaveSurplusTokenInVault.snap @@ -1 +1 @@ -104554 \ No newline at end of file +104597 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap b/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap index 4475c1ca..1168907c 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_runOutOfLiquidity.snap @@ -1 +1 @@ -25044269 \ No newline at end of file +25044312 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_simple.snap b/.forge-snapshots/CLPoolManagerTest#swap_simple.snap index 67c6dee8..4dedc7ce 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_simple.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_simple.snap @@ -1 +1 @@ -36336 \ No newline at end of file +36401 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap b/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap index 62871273..e580758f 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_useSurplusTokenAsInput.snap @@ -1 +1 @@ -103030 \ No newline at end of file +103140 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap b/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap index 0fd73b02..610ccdf8 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_withHooks.snap @@ -1 +1 @@ -41986 \ No newline at end of file +42051 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap b/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap index 0aecb1ad..9cc8594e 100644 --- a/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap +++ b/.forge-snapshots/CLPoolManagerTest#swap_withNative.snap @@ -1 +1 @@ -36339 \ No newline at end of file +36404 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap index 7b7d760c..366744e2 100644 --- a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap +++ b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Donate.snap @@ -1 +1 @@ -19448 \ No newline at end of file +19513 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap index 228723ef..3fdaecea 100644 --- a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap +++ b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_ModifyPosition.snap @@ -1 +1 @@ -27615 \ No newline at end of file +27680 \ No newline at end of file diff --git a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap index 9e1e60bf..4eb79bea 100644 --- a/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap +++ b/.forge-snapshots/CLPoolManagerTest#testNoOp_gas_Swap.snap @@ -1 +1 @@ -21897 \ No newline at end of file +21962 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#Vault.snap b/.forge-snapshots/VaultTest#Vault.snap index cb8c98cd..2354f680 100644 --- a/.forge-snapshots/VaultTest#Vault.snap +++ b/.forge-snapshots/VaultTest#Vault.snap @@ -1 +1 @@ -7016 \ No newline at end of file +7018 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap b/.forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap index cbf29f3c..466150e8 100644 --- a/.forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap +++ b/.forge-snapshots/VaultTest#lockSettledWhenAddLiquidity.snap @@ -1 +1 @@ -122519 \ No newline at end of file +122540 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap b/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap index 932d963e..f583bc35 100644 --- a/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap +++ b/.forge-snapshots/VaultTest#lockSettledWhenFlashloan.snap @@ -1 +1 @@ -158811 \ No newline at end of file +158832 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap b/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap index 37e2ed50..9638b220 100644 --- a/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap +++ b/.forge-snapshots/VaultTest#lockSettledWhenMultiHopSwap.snap @@ -1 +1 @@ -46974 \ No newline at end of file +47017 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap b/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap index e6f87cf8..ccf5975c 100644 --- a/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap +++ b/.forge-snapshots/VaultTest#lockSettledWhenSwap.snap @@ -1 +1 @@ -46973 \ No newline at end of file +47016 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testLock_NoOp.snap b/.forge-snapshots/VaultTest#testLock_NoOp.snap index 60052106..dcb77f93 100644 --- a/.forge-snapshots/VaultTest#testLock_NoOp.snap +++ b/.forge-snapshots/VaultTest#testLock_NoOp.snap @@ -1 +1 @@ -11532 \ No newline at end of file +11597 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap index 8aa8a574..4c89f9fe 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap @@ -1 +1 @@ -75609 \ No newline at end of file +79085 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap index 8ac5cf77..8eb6238d 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap @@ -1 +1 @@ -33010 \ No newline at end of file +36485 \ No newline at end of file diff --git a/src/Vault.sol b/src/Vault.sol index cbf5386f..1c68f7ae 100644 --- a/src/Vault.sol +++ b/src/Vault.sol @@ -126,7 +126,12 @@ contract Vault is IVault, VaultToken, Ownable { SettlementGuard.accountDelta(msg.sender, currency, -(paid.toInt128())); } - function settleAndRefund(Currency currency) external payable isLocked returns (uint256 paid, uint256 refund) { + function settleAndRefund(Currency currency, address to) + external + payable + isLocked + returns (uint256 paid, uint256 refund) + { paid = settle(currency); int256 afterCurrencyDelta = SettlementGuard.getCurrencyDelta(msg.sender, currency); @@ -138,7 +143,7 @@ contract Vault is IVault, VaultToken, Ownable { /// thus refund msg.sender and update accountDelta SettlementGuard.accountDelta(msg.sender, currency, refund.toInt128()); reservesOfVault[currency] -= refund; - currency.transfer(msg.sender, refund); + currency.transfer(to, refund); } } diff --git a/src/interfaces/IVault.sol b/src/interfaces/IVault.sol index d69d943f..297306b7 100644 --- a/src/interfaces/IVault.sol +++ b/src/interfaces/IVault.sol @@ -68,7 +68,9 @@ interface IVault is IVaultToken { function settle(Currency token) external payable returns (uint256 paid); /// @notice Called by the user to pay what is owed. If the payment is more than the debt, the surplus is refunded - function settleAndRefund(Currency token) external payable returns (uint256 paid, uint256 refund); + /// @param currency The currency to settle + /// @param to The address to refund the surplus to + function settleAndRefund(Currency currency, address to) external payable returns (uint256 paid, uint256 refund); /// @notice move the delta from target to the msg.sender, only payment delta can be moved /// @param currency The currency to settle diff --git a/test/vault/FakePoolManagerRouter.sol b/test/vault/FakePoolManagerRouter.sol index ba3aefb7..23f7cead 100644 --- a/test/vault/FakePoolManagerRouter.sol +++ b/test/vault/FakePoolManagerRouter.sol @@ -129,8 +129,10 @@ contract FakePoolManagerRouter { vault.settle{value: 5 ether}(CurrencyLibrary.NATIVE); vault.take(CurrencyLibrary.NATIVE, address(this), 5 ether); } else if (data[0] == 0x18) { - vault.settleAndRefund(poolKey.currency0); - vault.settleAndRefund(poolKey.currency1); + // call this method via vault.lock(abi.encodePacked(hex"18", alice)); + address to = address(uint160(uint256(bytes32(data[1:0x15]) >> 96))); + vault.settleAndRefund(poolKey.currency0, to); + vault.settleAndRefund(poolKey.currency1, to); } return ""; diff --git a/test/vault/Vault.t.sol b/test/vault/Vault.t.sol index a8f334c8..6042efb7 100644 --- a/test/vault/Vault.t.sol +++ b/test/vault/Vault.t.sol @@ -174,35 +174,39 @@ contract VaultTest is Test, GasSnapshot { } function testSettleAndRefund_WithErc20Transfer() public { + address alice = makeAddr("alice"); + // simulate someone transferred token to vault currency0.transfer(address(vault), 10 ether); assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 0 ether); - assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(alice)), 0 ether); // settle and refund vm.prank(address(fakePoolManagerRouter)); snapStart("VaultTest#testSettleAndRefund_WithErc20Transfer"); - vault.lock(hex"18"); + vault.lock(abi.encodePacked(hex"18", alice)); snapEnd(); // verify - assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 10 ether); - assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(alice)), 10 ether); } function testSettleAndRefund_WithoutErc20Transfer() public { + address alice = makeAddr("alice"); + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 0 ether); - assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(alice)), 0 ether); // settleAndRefund works even if there's no excess currency vm.prank(address(fakePoolManagerRouter)); snapStart("VaultTest#testSettleAndRefund_WithoutErc20Transfer"); - vault.lock(hex"18"); + vault.lock(abi.encodePacked(hex"18", alice)); snapEnd(); // verify assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(fakePoolManagerRouter)), 0 ether); - assertEq(IERC20(Currency.unwrap(currency1)).balanceOf(address(fakePoolManagerRouter)), 0 ether); + assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(alice)), 0 ether); } function testNotCorrectPoolManager() public { diff --git a/test/vault/VaultInvariant.t.sol b/test/vault/VaultInvariant.t.sol index 37ff8391..79b9f385 100644 --- a/test/vault/VaultInvariant.t.sol +++ b/test/vault/VaultInvariant.t.sol @@ -188,8 +188,8 @@ contract VaultPoolManager is Test { token0.transfer(address(vault), action.amt0); token1.transfer(address(vault), action.amt1); - vault.settleAndRefund(currency0); - vault.settleAndRefund(currency1); + vault.settleAndRefund(currency0, address(this)); + vault.settleAndRefund(currency1, address(this)); } else if (action.actionType == ActionType.SettleFor) { // hook cash out the fee ahead BalanceDelta delta = toBalanceDelta(int128(action.amt0), int128(action.amt1)); From c9123ff9cb7cfa65df2b5da9e6ddd5c23e430907 Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:24:23 +0800 Subject: [PATCH 3/5] feat: update to Snoopy implementation --- .forge-snapshots/VaultTest#Vault.snap | 2 +- ...testSettleAndRefund_WithErc20Transfer.snap | 2 +- ...tSettleAndRefund_WithoutErc20Transfer.snap | 2 +- src/Vault.sol | 22 +++++++++---------- src/interfaces/IVault.sol | 2 ++ 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/.forge-snapshots/VaultTest#Vault.snap b/.forge-snapshots/VaultTest#Vault.snap index 2354f680..f0d5c518 100644 --- a/.forge-snapshots/VaultTest#Vault.snap +++ b/.forge-snapshots/VaultTest#Vault.snap @@ -1 +1 @@ -7018 \ No newline at end of file +7068 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap index 4c89f9fe..ef7a8741 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap @@ -1 +1 @@ -79085 \ No newline at end of file +56125 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap index 8eb6238d..458f63d3 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap @@ -1 +1 @@ -36485 \ No newline at end of file +36463 \ No newline at end of file diff --git a/src/Vault.sol b/src/Vault.sol index 1c68f7ae..87b587f9 100644 --- a/src/Vault.sol +++ b/src/Vault.sol @@ -118,7 +118,7 @@ contract Vault is IVault, VaultToken, Ownable { } /// @inheritdoc IVault - function settle(Currency currency) public payable override isLocked returns (uint256 paid) { + function settle(Currency currency) external payable override isLocked returns (uint256 paid) { uint256 reservesBefore = reservesOfVault[currency]; reservesOfVault[currency] = currency.balanceOfSelf(); paid = reservesOfVault[currency] - reservesBefore; @@ -129,22 +129,22 @@ contract Vault is IVault, VaultToken, Ownable { function settleAndRefund(Currency currency, address to) external payable + override isLocked returns (uint256 paid, uint256 refund) { - paid = settle(currency); - - int256 afterCurrencyDelta = SettlementGuard.getCurrencyDelta(msg.sender, currency); - if (afterCurrencyDelta < 0) { - /// If user currencyDelta is negative (vault owes owner) after settle: either user have overpaid - /// or someone have transfer token to the vault. - refund = uint256(-afterCurrencyDelta); + paid = currency.balanceOfSelf() - reservesOfVault[currency]; + int256 currencyDelta = SettlementGuard.getCurrencyDelta(msg.sender, currency); - /// thus refund msg.sender and update accountDelta - SettlementGuard.accountDelta(msg.sender, currency, refund.toInt128()); - reservesOfVault[currency] -= refund; + if (currencyDelta >= 0 && paid > currencyDelta.toUint256()) { + // msg.sender owes vault but paid more than than whats owed + refund = paid - currencyDelta.toUint256(); + paid = currencyDelta.toUint256(); currency.transfer(to, refund); } + + reservesOfVault[currency] += paid; + SettlementGuard.accountDelta(msg.sender, currency, -(paid.toInt128())); } /// @inheritdoc IVault diff --git a/src/interfaces/IVault.sol b/src/interfaces/IVault.sol index 297306b7..b3f0bd9e 100644 --- a/src/interfaces/IVault.sol +++ b/src/interfaces/IVault.sol @@ -70,6 +70,8 @@ interface IVault is IVaultToken { /// @notice Called by the user to pay what is owed. If the payment is more than the debt, the surplus is refunded /// @param currency The currency to settle /// @param to The address to refund the surplus to + /// @return paid The amount paid + /// @return refund The amount refunded function settleAndRefund(Currency currency, address to) external payable returns (uint256 paid, uint256 refund); /// @notice move the delta from target to the msg.sender, only payment delta can be moved From 919b1648645d7da9922e015ba238092f2545baea Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:44:50 +0800 Subject: [PATCH 4/5] feat: add negative balance delta test --- .forge-snapshots/VaultTest#testLock_NoOp.snap | 2 +- ...tTest#testSettleAndRefund_WithErc20Transfer.snap | 2 +- ...st#testSettleAndRefund_WithoutErc20Transfer.snap | 2 +- src/Vault.sol | 8 ++++---- test/vault/FakePoolManagerRouter.sol | 7 +++++++ test/vault/Vault.t.sol | 13 +++++++++++++ 6 files changed, 27 insertions(+), 7 deletions(-) diff --git a/.forge-snapshots/VaultTest#testLock_NoOp.snap b/.forge-snapshots/VaultTest#testLock_NoOp.snap index dcb77f93..ec8b9590 100644 --- a/.forge-snapshots/VaultTest#testLock_NoOp.snap +++ b/.forge-snapshots/VaultTest#testLock_NoOp.snap @@ -1 +1 @@ -11597 \ No newline at end of file +11692 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap index ef7a8741..734fb9ea 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap @@ -1 +1 @@ -56125 \ No newline at end of file +56136 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap index 458f63d3..17e1c14a 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap @@ -1 +1 @@ -36463 \ No newline at end of file +36474 \ No newline at end of file diff --git a/src/Vault.sol b/src/Vault.sol index 87b587f9..95f25d9b 100644 --- a/src/Vault.sol +++ b/src/Vault.sol @@ -134,12 +134,12 @@ contract Vault is IVault, VaultToken, Ownable { returns (uint256 paid, uint256 refund) { paid = currency.balanceOfSelf() - reservesOfVault[currency]; - int256 currencyDelta = SettlementGuard.getCurrencyDelta(msg.sender, currency); + int256 currentDelta = SettlementGuard.getCurrencyDelta(msg.sender, currency); - if (currencyDelta >= 0 && paid > currencyDelta.toUint256()) { + if (currentDelta >= 0 && paid > currentDelta.toUint256()) { // msg.sender owes vault but paid more than than whats owed - refund = paid - currencyDelta.toUint256(); - paid = currencyDelta.toUint256(); + refund = paid - currentDelta.toUint256(); + paid = currentDelta.toUint256(); currency.transfer(to, refund); } diff --git a/test/vault/FakePoolManagerRouter.sol b/test/vault/FakePoolManagerRouter.sol index 23f7cead..6c9f4090 100644 --- a/test/vault/FakePoolManagerRouter.sol +++ b/test/vault/FakePoolManagerRouter.sol @@ -133,6 +133,13 @@ contract FakePoolManagerRouter { address to = address(uint160(uint256(bytes32(data[1:0x15]) >> 96))); vault.settleAndRefund(poolKey.currency0, to); vault.settleAndRefund(poolKey.currency1, to); + } else if (data[0] == 0x19) { + poolManager.mockAccounting(poolKey, 3 ether, -3 ether); + vault.settle(poolKey.currency0); + + /// try to call settleAndRefund should not revert + vault.settleAndRefund(poolKey.currency1, address(this)); + vault.take(poolKey.currency1, address(this), 3 ether); } return ""; diff --git a/test/vault/Vault.t.sol b/test/vault/Vault.t.sol index 6042efb7..dd436db6 100644 --- a/test/vault/Vault.t.sol +++ b/test/vault/Vault.t.sol @@ -209,6 +209,19 @@ contract VaultTest is Test, GasSnapshot { assertEq(IERC20(Currency.unwrap(currency0)).balanceOf(address(alice)), 0 ether); } + function testSettleAndRefund_NegativeBalanceDelta() public { + // pre-req: ensure vault has some value in reserveOfVault[] before + currency0.transfer(address(vault), 10 ether); + currency1.transfer(address(vault), 10 ether); + vm.prank(address(fakePoolManagerRouter)); + vault.lock(hex"02"); + + // settleAndRefund should not revert even if negative balanceDelta + currency0.transfer(address(vault), 3 ether); + vm.prank(address(fakePoolManagerRouter)); + vault.lock(hex"19"); + } + function testNotCorrectPoolManager() public { // router => vault.lock // vault.lock => periphery.lockAcquired From 236a1d3c750b70cb5a42638bffe9dacdc75ccd08 Mon Sep 17 00:00:00 2001 From: ChefMist <133624774+ChefMist@users.noreply.github.com> Date: Thu, 21 Mar 2024 14:41:38 +0800 Subject: [PATCH 5/5] bug: move transfer only at the end to prevent reentrancy --- .forge-snapshots/VaultTest#Vault.snap | 2 +- .../VaultTest#testSettleAndRefund_WithErc20Transfer.snap | 2 +- .../VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap | 2 +- src/Vault.sol | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.forge-snapshots/VaultTest#Vault.snap b/.forge-snapshots/VaultTest#Vault.snap index f0d5c518..c5472716 100644 --- a/.forge-snapshots/VaultTest#Vault.snap +++ b/.forge-snapshots/VaultTest#Vault.snap @@ -1 +1 @@ -7068 \ No newline at end of file +7075 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap index 734fb9ea..b0d10039 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithErc20Transfer.snap @@ -1 +1 @@ -56136 \ No newline at end of file +56176 \ No newline at end of file diff --git a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap index 17e1c14a..806af93a 100644 --- a/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap +++ b/.forge-snapshots/VaultTest#testSettleAndRefund_WithoutErc20Transfer.snap @@ -1 +1 @@ -36474 \ No newline at end of file +36514 \ No newline at end of file diff --git a/src/Vault.sol b/src/Vault.sol index 95f25d9b..4acc2aa4 100644 --- a/src/Vault.sol +++ b/src/Vault.sol @@ -140,11 +140,12 @@ contract Vault is IVault, VaultToken, Ownable { // msg.sender owes vault but paid more than than whats owed refund = paid - currentDelta.toUint256(); paid = currentDelta.toUint256(); - currency.transfer(to, refund); } reservesOfVault[currency] += paid; SettlementGuard.accountDelta(msg.sender, currency, -(paid.toInt128())); + + if (refund > 0) currency.transfer(to, refund); } /// @inheritdoc IVault