diff --git a/contracts/vortex/CarbonVortex.sol b/contracts/vortex/CarbonVortex.sol index 3ea3076e..2f03d896 100644 --- a/contracts/vortex/CarbonVortex.sol +++ b/contracts/vortex/CarbonVortex.sol @@ -381,17 +381,17 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, } // go through all tokens and start / reset dutch auction if necessary - for (uint256 i = 0; i < tokens.length; ++i) { + for (uint256 i = 0; i < len; i = uncheckedInc(i)) { Token token = tokens[i]; uint256 totalFeeAmount = feeAmounts[i]; - // skip token if no fees have accumulated or token pair is disabled - if (totalFeeAmount == 0 || _disabledPairs[token]) { - continue; - } // skip the final target token if (token == _finalTargetToken) { continue; } + // skip token if no fees have accumulated or token pair is disabled + if (totalFeeAmount == 0 || _disabledPairs[token]) { + continue; + } // get fee and reward amounts uint256 rewardAmount = rewardAmounts[i]; uint256 feeAmount = totalFeeAmount - rewardAmount; @@ -412,10 +412,11 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, _resetTradingTarget(rewardAmount); } } else { + uint128 tradingAmount = _amountAvailableForTrading(token); if ( !_tradingEnabled(token) || - _amountAvailableForTrading(token) - feeAmount < _minTokenSaleAmounts[token] || - _amountAvailableForTrading(token) > _minTokenSaleAmountMultiplier * _minTokenSaleAmounts[token] || + tradingAmount - feeAmount < _minTokenSaleAmounts[token] || + tradingAmount > _minTokenSaleAmountMultiplier * _minTokenSaleAmounts[token] || _auctionPriceIsBelowMinimum(token) ) { // reset trading for token @@ -432,12 +433,8 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, * @notice resets dutch auction for target token -> TKN trades and set the initial price to max possible */ function _resetTrading(Token token, uint256 rewardAmount) private { - Price memory price = Price({ - sourceAmount: INITIAL_PRICE_SOURCE_AMOUNT, - targetAmount: INITIAL_PRICE_TARGET_AMOUNT - }); - _tradingStartTimes[token] = uint32(block.timestamp); - _initialPrice[token] = price; + // reset the auction with the initial price + Price memory price = _resetAuction(token); // set min token sale amount _setMinTokenSaleAmount(token, (token.balanceOf(address(this)) - rewardAmount).toUint128() / 2); emit TradingReset({ token: token, price: price }); @@ -447,12 +444,9 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, * @notice resets dutch auction for finalTargetToken->targetToken trades and set the initial price to max possible */ function _resetTradingTarget(uint256 rewardAmount) private { - Price memory price = Price({ - sourceAmount: INITIAL_PRICE_SOURCE_AMOUNT, - targetAmount: INITIAL_PRICE_TARGET_AMOUNT - }); - _tradingStartTimes[_targetToken] = uint32(block.timestamp); - _initialPrice[_targetToken] = price; + // reset the auction with the initial price + Price memory price = _resetAuction(_targetToken); + // reset the current target token sale amount _targetTokenSaleAmount.current = Math .min(_targetToken.balanceOf(address(this)) - rewardAmount, _targetTokenSaleAmount.initial) .toUint128(); @@ -896,7 +890,7 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, if (token == _targetToken) { return _targetTokenSaleAmount.current; } else { - return uint128(token.balanceOf(address(this))); + return token.balanceOf(address(this)).toUint128(); } } @@ -964,6 +958,19 @@ contract CarbonVortex is ICarbonVortex, Upgradeable, ReentrancyGuardUpgradeable, } } + /** + * @dev helper function to reset the auction to the initial price + */ + function _resetAuction(Token token) private returns (Price memory) { + Price memory price = Price({ + sourceAmount: INITIAL_PRICE_SOURCE_AMOUNT, + targetAmount: INITIAL_PRICE_TARGET_AMOUNT + }); + _tradingStartTimes[token] = uint32(block.timestamp); + _initialPrice[token] = price; + return price; + } + function uncheckedInc(uint256 i) private pure returns (uint256 j) { unchecked { j = i + 1; diff --git a/contracts/vortex/interfaces/ICarbonVortex.sol b/contracts/vortex/interfaces/ICarbonVortex.sol index 69b99aef..538d8edc 100644 --- a/contracts/vortex/interfaces/ICarbonVortex.sol +++ b/contracts/vortex/interfaces/ICarbonVortex.sol @@ -57,7 +57,7 @@ interface ICarbonVortex is IUpgradeable { /** * @dev triggered when tokens have been withdrawn by the admin */ - event FundsWithdrawn(Token[] tokens, uint256[] amounts, address indexed caller, address indexed target); + event FundsWithdrawn(Token[] indexed tokens, address indexed caller, address indexed target, uint256[] amounts); /** * @notice triggered when the price reset multiplier is updated @@ -163,18 +163,18 @@ interface ICarbonVortex is IUpgradeable { /** * @notice returns the target amount expected given a source amount */ - function expectedTradeReturn(Token token, uint128 sourceAmount) external view returns (uint128 targetAmount); + function expectedTradeReturn(Token token, uint128 sourceAmount) external view returns (uint128); /** * @notice returns the source amount required given a target amount */ - function expectedTradeInput(Token token, uint128 targetAmount) external view returns (uint128 sourceAmount); + function expectedTradeInput(Token token, uint128 targetAmount) external view returns (uint128); /** * @notice returns the current token price (targetToken / TKN) * @notice if token == targetToken, returns finalTargetToken / targetToken price */ - function tokenPrice(Token token) external view returns (Price memory price); + function tokenPrice(Token token) external view returns (Price memory); /** * @dev returns the total available fees for the given token diff --git a/test/forge/CarbonVortex.t.sol b/test/forge/CarbonVortex.t.sol index 489ecab2..f03e19c3 100644 --- a/test/forge/CarbonVortex.t.sol +++ b/test/forge/CarbonVortex.t.sol @@ -85,7 +85,7 @@ contract CarbonVortexTest is TestFixture { /** * @dev triggered when tokens have been withdrawn by the admin */ - event FundsWithdrawn(Token[] tokens, uint256[] amounts, address indexed caller, address indexed target); + event FundsWithdrawn(Token[] indexed tokens, address indexed caller, address indexed target, uint256[] amounts); /** * @dev triggered when tokens have been withdrawn from the vault (Vault event) @@ -3326,7 +3326,7 @@ contract CarbonVortexTest is TestFixture { token1.safeTransfer(address(carbonVortex), withdrawAmounts[0]); vm.expectEmit(); - emit FundsWithdrawn(tokens, withdrawAmounts, admin, user2); + emit FundsWithdrawn(tokens, admin, user2, withdrawAmounts); // withdraw token to user2 carbonVortex.withdrawFunds(tokens, user2, withdrawAmounts); diff --git a/test/forge/VortexTestCaseParser.t.sol b/test/forge/VortexTestCaseParser.t.sol index fc494364..526868f6 100644 --- a/test/forge/VortexTestCaseParser.t.sol +++ b/test/forge/VortexTestCaseParser.t.sol @@ -3,11 +3,13 @@ pragma solidity 0.8.19; import { Test } from "forge-std/Test.sol"; import { stdJson } from "forge-std/StdJson.sol"; +import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; contract VortexTestCaseParser is Test { using stdJson for string; + using SafeCast for uint256; struct PriceAtTimestamp { uint128 sourceAmount; @@ -90,9 +92,9 @@ contract VortexTestCaseParser is Test { ) private pure returns (PriceAtTimestamp memory priceAtTimestamp) { return PriceAtTimestamp({ - timestamp: uint32(stringToUint(priceAtTimestampString.timestamp)), - sourceAmount: uint128(stringToUint(priceAtTimestampString.sourceAmount)), - targetAmount: uint128(stringToUint(priceAtTimestampString.targetAmount)) + timestamp: stringToUint(priceAtTimestampString.timestamp).toUint32(), + sourceAmount: stringToUint(priceAtTimestampString.sourceAmount).toUint128(), + targetAmount: stringToUint(priceAtTimestampString.targetAmount).toUint128() }); }