diff --git a/contracts/vortex/CarbonVortex.sol b/contracts/vortex/CarbonVortex.sol index 93cab273..cbf53d12 100644 --- a/contracts/vortex/CarbonVortex.sol +++ b/contracts/vortex/CarbonVortex.sol @@ -631,6 +631,10 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, if (sourceAmount == 0) { revert InvalidTrade(); } + // revert if unnecessary native token is received + if (_targetToken != NATIVE_TOKEN && msg.value > 0) { + revert UnnecessaryNativeTokenReceived(); + } // check enough target token (if target token is native) has been sent for the trade if (_targetToken == NATIVE_TOKEN && msg.value < sourceAmount) { revert InsufficientNativeTokenSent(); @@ -675,6 +679,10 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, if (sourceAmount == 0) { revert InvalidTrade(); } + // revert if unnecessary native token is received + if (_finalTargetToken != NATIVE_TOKEN && msg.value > 0) { + revert UnnecessaryNativeTokenReceived(); + } // check enough final target token (if final target token is native) has been sent for the trade if (_finalTargetToken == NATIVE_TOKEN) { diff --git a/contracts/vortex/interfaces/ICarbonVortex.sol b/contracts/vortex/interfaces/ICarbonVortex.sol index bf964e57..368ba60f 100644 --- a/contracts/vortex/interfaces/ICarbonVortex.sol +++ b/contracts/vortex/interfaces/ICarbonVortex.sol @@ -18,6 +18,7 @@ interface ICarbonVortex is IUpgradeable { error PairDisabled(); error InsufficientNativeTokenSent(); error InsufficientAmountForTrading(); + error UnnecessaryNativeTokenReceived(); struct Price { uint128 sourceAmount; diff --git a/test/forge/CarbonVortex.t.sol b/test/forge/CarbonVortex.t.sol index da5d2343..4291a548 100644 --- a/test/forge/CarbonVortex.t.sol +++ b/test/forge/CarbonVortex.t.sol @@ -1574,6 +1574,64 @@ contract CarbonVortexTest is TestFixture { assertEq(balanceGain, sourceAmount); } + /// @dev test that sending any ETH with the transaction + /// @dev on target -> token trades should revert if targetToken != NATIVE_TOKEN + function testShouldRevertIfUnnecessaryNativeTokenSentOnTargetToFinalTargetTrades() public { + targetToken = bnt; + finalTargetToken = NATIVE_TOKEN; + Token token = token1; + // Deploy new Carbon Vortex with the target token set to a token different than native token + deployCarbonVortex(address(carbonController), vault, oldVortex, transferAddress, targetToken, finalTargetToken); + vm.prank(admin); + // set fees + uint256 accumulatedFees = 100 ether; + carbonController.testSetAccumulatedFees(token, accumulatedFees); + + vm.startPrank(user1); + + // execute + Token[] memory tokens = new Token[](1); + tokens[0] = token; + carbonVortex.execute(tokens); + + // trade target for final target + uint128 targetAmount = 1 ether; + + // advance time + vm.warp(45 days); + + // trade + vm.expectRevert(ICarbonVortex.UnnecessaryNativeTokenReceived.selector); + carbonVortex.trade{ value: 1 }(token, targetAmount); + } + + /// @dev test that sending any ETH with the transaction + /// @dev on final target -> target token trades should revert if finalTargetToken != NATIVE_TOKEN + function testShouldRevertIfUnnecessaryNativeTokenSentOnFinalTargetToTargetTrades() public { + Token token = targetToken; + vm.prank(admin); + // set fees + uint256 accumulatedFees = 100 ether; + carbonController.testSetAccumulatedFees(token, accumulatedFees); + + vm.startPrank(user1); + + // execute + Token[] memory tokens = new Token[](1); + tokens[0] = token; + carbonVortex.execute(tokens); + + // trade target for final target + uint128 targetAmount = 1 ether; + + // advance time + vm.warp(45 days); + + // trade + vm.expectRevert(ICarbonVortex.UnnecessaryNativeTokenReceived.selector); + carbonVortex.trade{ value: 1 }(token, targetAmount); + } + /// @dev test that sending less than the sourceAmount of ETH with the transaction /// @dev on final target -> target token trades should revert if finalTarget == NATIVE_TOKEN function testShouldRevertIfInsufficientNativeTokenSentOnFinalTargetToTargetTokenTrade() public {