Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
3xHarry committed Apr 6, 2023
1 parent 413b28a commit f6e9e28
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 33 deletions.
58 changes: 43 additions & 15 deletions src/v2/Carousel/Carousel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ contract Carousel is VaultV2 {
// Earthquake parameters
uint256 public relayerFee;
uint256 public depositFee;
uint256 public minQueueDeposit;
IERC20 public immutable emissionsToken;

mapping(address => uint256) public ownerToRollOverQueueIndex;
Expand Down Expand Up @@ -55,6 +56,7 @@ contract Carousel is VaultV2 {
emissionsToken = IERC20(_data.emissionsToken);
relayerFee = _data.relayerFee;
depositFee = _data.depositFee;
minQueueDeposit = _data.minQueueDeposit;

// set epoch 0 to be allways available to deposit into Queue
epochExists[0] = true;
Expand Down Expand Up @@ -85,7 +87,7 @@ contract Carousel is VaultV2 {
override(VaultV2)
epochIdExists(_id)
epochHasNotStarted(_id)
minRequiredDeposit(_assets)
minRequiredDeposit(_assets, _id)
nonReentrant
{
// make sure that epoch exists
Expand All @@ -103,7 +105,7 @@ contract Carousel is VaultV2 {
external
payable
override(VaultV2)
minRequiredDeposit(msg.value)
minRequiredDeposit(msg.value, _id)
epochIdExists(_id)
epochHasNotStarted(_id)
nonReentrant
Expand Down Expand Up @@ -240,7 +242,7 @@ contract Carousel is VaultV2 {
uint256 _epochId,
uint256 _assets,
address _receiver
) public epochIdExists(_epochId) minRequiredDeposit(_assets) {
) public epochIdExists(_epochId) minRequiredDeposit(_assets, _epochId) {
// check if sender is approved by owner
if (
msg.sender != _receiver &&
Expand Down Expand Up @@ -332,16 +334,26 @@ contract Carousel is VaultV2 {
while ((length - _operations) <= i) {
// this loop impelements FILO (first in last out) stack to reduce gas cost and improve code readability
// changing it to FIFO (first in first out) would require more code changes and would be more expensive
// @note non neglectable mint deposit creates barriers for attackers to DDOS the queue

uint256 assetsToDeposit = queue[i].assets;

if (depositFee > 0) {
(uint256 feeAmount, uint256 assetsAfterFee) = getEpochDepositFee(_epochId, assetsToDeposit);
assetsToDeposit = assetsAfterFee;
_asset().safeTransfer(treasury, feeAmount);
}

_mintShares(
queue[i].receiver,
_epochId,
queue[i].assets - relayerFee
assetsToDeposit - relayerFee
);
emit Deposit(
msg.sender,
queue[i].receiver,
_epochId,
queue[i].assets - relayerFee
assetsToDeposit - relayerFee
);
depositQueue.pop();
if (i == 0) break;
Expand Down Expand Up @@ -483,14 +495,8 @@ contract Carousel is VaultV2 {
uint256 assetsToDeposit = _assets;

if (depositFee > 0) {
(uint256 maxX, , uint256 minX) = getEpochConfig(_id);
// deposit fee is calcualted linearly between time of epoch creation and epoch starting (deposit window)
// this is because late depositors have an informational advantage
uint256 fee = _calculateFeePercent(int256(minX), int256(maxX));
// min minRequiredDeposit modifier ensures that _assets has high enough value to not devide by 0
// 0.5% = multiply by 10000 then divide by 50
uint256 feeAmount = _assets.mulDivDown(fee, 10000);
assetsToDeposit = _assets - feeAmount;
(uint256 feeAmount, uint256 assetsAfterFee) = getEpochDepositFee(_id, _assets);
assetsToDeposit = assetsAfterFee;
_asset().safeTransfer(treasury, feeAmount);
}

Expand Down Expand Up @@ -628,6 +634,27 @@ contract Carousel is VaultV2 {
return ownerToRollOverQueueIndex[_owner] - 1;
}

/** @notice retruns deposit fee at this time
* @param _id epoch id
* @param _assets amount of assets
* @return feeAmount fee amount
* @return _assetsAfterFee assets after fee
*/
function getEpochDepositFee(uint256 _id, uint256 _assets)
public
view
returns (uint256 feeAmount, uint256 _assetsAfterFee)
{
(uint256 maxX, , uint256 minX) = getEpochConfig(_id);
// deposit fee is calcualted linearly between time of epoch creation and epoch starting (deposit window)
// this is because late depositors have an informational advantage
uint256 fee = _calculateFeePercent(int256(minX), int256(maxX));
// min minRequiredDeposit modifier ensures that _assets has high enough value to not devide by 0
// 0.5% = multiply by 10000 then divide by 50
feeAmount = _assets.mulDivDown(fee, 10000);
_assetsAfterFee = _assets - feeAmount;
}

/** @notice returns the emissions to withdraw
* @param _id epoch id
* @param _assets amount of assets to withdraw
Expand Down Expand Up @@ -733,6 +760,7 @@ contract Carousel is VaultV2 {
address emissionsToken;
uint256 relayerFee;
uint256 depositFee;
uint256 minQueueDeposit;
}

/*//////////////////////////////////////////////////////////////
Expand All @@ -742,8 +770,8 @@ contract Carousel is VaultV2 {
/** @notice checks if deposit is greater than relayer fee
* @param _assets amount of assets to deposit
*/
modifier minRequiredDeposit(uint256 _assets) {
if (_assets < relayerFee) revert MinDeposit();
modifier minRequiredDeposit(uint256 _assets, uint256 _epochId) {
if (_epochId == 0 && _assets < minQueueDeposit) revert MinDeposit();
_;
}

Expand Down
7 changes: 5 additions & 2 deletions src/v2/Carousel/CarouselFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ contract CarouselFactory is VaultFactoryV2 {
treasury,
address(emissionsToken),
_marketCalldata.relayerFee,
_marketCalldata.depositFee
_marketCalldata.depositFee,
_marketCalldata.minQueueDeposit
)
);

Expand All @@ -95,7 +96,8 @@ contract CarouselFactory is VaultFactoryV2 {
treasury,
address(emissionsToken),
_marketCalldata.relayerFee,
_marketCalldata.depositFee
_marketCalldata.depositFee,
_marketCalldata.minQueueDeposit
)
);

Expand Down Expand Up @@ -212,6 +214,7 @@ contract CarouselFactory is VaultFactoryV2 {
address controller;
uint256 relayerFee;
uint256 depositFee;
uint256 minQueueDeposit;
}

/*//////////////////////////////////////////////////////////////
Expand Down
4 changes: 3 additions & 1 deletion src/v2/libraries/CarouselCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ library CarouselCreator {
address emissionsToken;
uint256 relayerFee;
uint256 depositFee;
uint256 minQueueDeposit;
}

function createCarousel(CarouselMarketConfiguration memory _marketConfig)
Expand All @@ -37,7 +38,8 @@ library CarouselCreator {
_marketConfig.treasury,
_marketConfig.emissionsToken,
_marketConfig.relayerFee,
_marketConfig.depositFee
_marketConfig.depositFee,
_marketConfig.minQueueDeposit
)
)
);
Expand Down
6 changes: 4 additions & 2 deletions test/V2/Carousel/CarouselFactoryTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ contract CarouselFactoryTest is Helper {
symbol,
controller,
relayerFee,
depositFee
depositFee,
1 ether
)
);

Expand Down Expand Up @@ -266,7 +267,8 @@ contract CarouselFactoryTest is Helper {
symbol,
controller,
relayerFee,
depositFee)
depositFee,
1 ether)
);
}

Expand Down
3 changes: 2 additions & 1 deletion test/V2/Carousel/CarouselTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ contract CarouselTest is Helper {
TREASURY,
emissionsToken,
relayerFee,
depositFee
depositFee,
1 ether
)
);

Expand Down
10 changes: 5 additions & 5 deletions test/V2/Helper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Helper is Test {
uint256 public constant STRIKE = 1000000000000000000;
uint256 public constant COLLATERAL_MINUS_FEES = 21989999998407999999;
uint256 public constant COLLATERAL_MINUS_FEES_DIV10 = 2198999999840799999;
uint256 public constant COLLATERAL_MINUS_FEES = 21989999998398551453;
uint256 public constant COLLATERAL_MINUS_FEES_DIV10 = 2198999999839855145;
uint256 public constant NEXT_COLLATERAL_MINUS_FEES = 21827317001456829250;
uint256 public constant USER1_EMISSIONS_AFTER_WITHDRAW = 1096380172807730660741;
uint256 public constant USER2_EMISSIONS_AFTER_WITHDRAW = 96380172807730660741;
uint256 public constant USER_AMOUNT_AFTER_WITHDRAW = 13112658495641799945;
uint256 public constant USER1_EMISSIONS_AFTER_WITHDRAW = 1096655439903230405185;
uint256 public constant USER2_EMISSIONS_AFTER_WITHDRAW = 96655439903230405185;
uint256 public constant USER_AMOUNT_AFTER_WITHDRAW = 13112658495640855090;
address public constant ADMIN = address(0x1);
address public constant WETH = address(0x888);
address public constant TREASURY = address(0x777);
Expand Down
18 changes: 11 additions & 7 deletions test/V2/e2e/EndToEndCarouselTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ contract EndToEndCarouselTest is Helper {
symbol,
address(controller),
relayerFee,
depositFee)
depositFee,
1 ether)
);

// deploy epoch
Expand Down Expand Up @@ -168,13 +169,16 @@ contract EndToEndCarouselTest is Helper {
Carousel(collateral).mintDepositInQueue(epochId, collateralQueueLength);
Carousel(premium).mintDepositInQueue(epochId, premiumQueueLength);

(,uint256 collatBalanceAfterFee) = Carousel(collateral).getEpochDepositFee(epochId, 10 ether);
(,uint256 premiumBalanceAfterFee) = Carousel(premium).getEpochDepositFee(epochId, 2 ether);

//assert balance and emissions
assertEq(Carousel(collateral).balanceOf(USER, epochId), 10 ether - relayerFee);
assertEq(Carousel(collateral).balanceOfEmissions(USER, epochId), 10 ether - relayerFee);
assertEq(Carousel(collateral).balanceOf(USER2, epochId), 10 ether - relayerFee);
assertEq(Carousel(collateral).balanceOfEmissions(USER2, epochId), 10 ether - relayerFee);
assertEq(Carousel(premium).balanceOf(USER, epochId), 2 ether - relayerFee);
assertEq(Carousel(premium).balanceOfEmissions(USER, epochId), 2 ether - relayerFee);
assertEq(Carousel(collateral).balanceOf(USER, epochId), collatBalanceAfterFee - relayerFee);
assertEq(Carousel(collateral).balanceOfEmissions(USER, epochId), collatBalanceAfterFee - relayerFee);
assertEq(Carousel(collateral).balanceOf(USER2, epochId), collatBalanceAfterFee - relayerFee);
assertEq(Carousel(collateral).balanceOfEmissions(USER2, epochId), collatBalanceAfterFee - relayerFee);
assertEq(Carousel(premium).balanceOf(USER, epochId), premiumBalanceAfterFee - relayerFee);
assertEq(Carousel(premium).balanceOfEmissions(USER, epochId), premiumBalanceAfterFee - relayerFee);
assertEq(Carousel(premium).balanceOf(USER2, epochId), 0);
assertEq(Carousel(premium).balanceOfEmissions(USER2, epochId), 0);

Expand Down

0 comments on commit f6e9e28

Please sign in to comment.