Skip to content

Commit 4dc0b07

Browse files
authored
Merge pull request #56 from euler-xyz/alt-protocol-fee
clean protocol fee impl
2 parents 8109224 + 18b9165 commit 4dc0b07

File tree

5 files changed

+45
-23
lines changed

5 files changed

+45
-23
lines changed

src/EulerSwap.sol

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ contract EulerSwap is IEulerSwap, EVCUtil {
2323
address public immutable eulerAccount;
2424
uint112 public immutable equilibriumReserve0;
2525
uint112 public immutable equilibriumReserve1;
26-
uint256 public immutable feeMultiplier;
26+
uint256 public immutable fee;
27+
uint256 public immutable protocolFee;
28+
address public immutable protocolFeeRecipient;
2729

2830
uint256 public immutable priceX;
2931
uint256 public immutable priceY;
@@ -83,7 +85,9 @@ contract EulerSwap is IEulerSwap, EVCUtil {
8385
equilibriumReserve1 = params.equilibriumReserve1;
8486
reserve0 = params.currReserve0;
8587
reserve1 = params.currReserve1;
86-
feeMultiplier = 1e18 - params.fee;
88+
fee = params.fee;
89+
protocolFee = 0.1e18;
90+
protocolFeeRecipient = address(0);
8791

8892
// Curve params
8993

@@ -120,11 +124,8 @@ contract EulerSwap is IEulerSwap, EVCUtil {
120124

121125
// Deposit all available funds, adjust received amounts downward to collect fees
122126

123-
uint256 amount0In = IERC20(asset0).balanceOf(address(this));
124-
if (amount0In > 0) amount0In = depositAssets(vault0, amount0In) * feeMultiplier / 1e18;
125-
126-
uint256 amount1In = IERC20(asset1).balanceOf(address(this));
127-
if (amount1In > 0) amount1In = depositAssets(vault1, amount1In) * feeMultiplier / 1e18;
127+
uint256 amount0In = depositAssets(asset0, vault0);
128+
uint256 amount1In = depositAssets(asset1, vault1);
128129

129130
// Verify curve invariant is satisfied
130131

@@ -211,14 +212,29 @@ contract EulerSwap is IEulerSwap, EVCUtil {
211212
}
212213

213214
/// @notice Deposits assets into a vault and automatically repays any outstanding debt
215+
/// @param asset The address of the underlying asset
214216
/// @param vault The address of the vault to deposit into
215-
/// @param amount The amount of assets to deposit
216217
/// @return The amount of assets successfully deposited
217218
/// @dev This function attempts to deposit assets into the specified vault.
218219
/// @dev If the deposit fails with E_ZeroShares error, it safely returns 0 (this happens with very small amounts).
219220
/// @dev After successful deposit, if the user has any outstanding controller-enabled debt, it attempts to repay it.
220221
/// @dev If all debt is repaid, the controller is automatically disabled to reduce gas costs in future operations.
221-
function depositAssets(address vault, uint256 amount) internal returns (uint256) {
222+
function depositAssets(address asset, address vault) internal returns (uint256) {
223+
uint256 amount = IERC20(asset).balanceOf(address(this));
224+
if (amount == 0) return 0;
225+
226+
uint256 feeAmount = amount * fee / 1e18;
227+
228+
{
229+
uint256 protocolFeeAmount = feeAmount * protocolFee / 1e18;
230+
231+
if (protocolFeeAmount != 0) {
232+
IERC20(asset).transfer(protocolFeeRecipient, protocolFeeAmount);
233+
amount -= protocolFeeAmount;
234+
feeAmount -= protocolFeeAmount;
235+
}
236+
}
237+
222238
uint256 deposited;
223239

224240
if (IEVC(evc).isControllerEnabled(eulerAccount, vault)) {
@@ -238,13 +254,13 @@ contract EulerSwap is IEulerSwap, EVCUtil {
238254
try IEVault(vault).deposit(amount, eulerAccount) {}
239255
catch (bytes memory reason) {
240256
require(bytes4(reason) == EVKErrors.E_ZeroShares.selector, DepositFailure(reason));
241-
return deposited;
257+
amount = 0;
242258
}
243259

244260
deposited += amount;
245261
}
246262

247-
return deposited;
263+
return deposited > feeAmount ? deposited - feeAmount : 0;
248264
}
249265

250266
/// @notice Approves tokens for a given vault, supporting both standard approvals and permit2

src/EulerSwapFactory.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil {
2323
address indexed asset1,
2424
address vault0,
2525
address vault1,
26-
uint256 indexed feeMultiplier,
26+
uint256 indexed fee,
2727
address eulerAccount,
2828
uint256 reserve0,
2929
uint256 reserve1,
@@ -70,7 +70,7 @@ contract EulerSwapFactory is IEulerSwapFactory, EVCUtil {
7070
pool.asset1(),
7171
params.vault0,
7272
params.vault1,
73-
pool.feeMultiplier(),
73+
pool.fee(),
7474
params.eulerAccount,
7575
params.currReserve0,
7676
params.currReserve1,

src/EulerSwapPeriphery.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery {
105105
);
106106
require(amount <= type(uint112).max, SwapLimitExceeded());
107107

108-
uint256 feeMultiplier = eulerSwap.feeMultiplier();
108+
uint256 fee = eulerSwap.fee();
109109
(uint112 reserve0, uint112 reserve1,) = eulerSwap.getReserves();
110110

111-
// exactIn: decrease received amountIn, rounding down
112-
if (exactIn) amount = amount * feeMultiplier / 1e18;
111+
// exactIn: decrease effective amountIn
112+
if (exactIn) amount = amount - (amount * fee / 1e18);
113113

114114
bool asset0IsInput = checkTokens(eulerSwap, tokenIn, tokenOut);
115115
(uint256 inLimit, uint256 outLimit) = calcLimits(eulerSwap, asset0IsInput);
@@ -124,8 +124,8 @@ contract EulerSwapPeriphery is IEulerSwapPeriphery {
124124
require(amount <= outLimit && quote <= inLimit, SwapLimitExceeded());
125125
}
126126

127-
// exactOut: increase required quote(amountIn), rounding up
128-
if (!exactIn) quote = (quote * 1e18 + (feeMultiplier - 1)) / feeMultiplier;
127+
// exactOut: inflate required amountIn
128+
if (!exactIn) quote = (quote * 1e18) / (1e18 - fee);
129129

130130
return quote;
131131
}

src/interfaces/IEulerSwap.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ interface IEulerSwap {
5050
function eulerAccount() external view returns (address);
5151
function equilibriumReserve0() external view returns (uint112);
5252
function equilibriumReserve1() external view returns (uint112);
53-
function feeMultiplier() external view returns (uint256);
53+
function fee() external view returns (uint256);
54+
function protocolFee() external view returns (uint256);
55+
function protocolFeeRecipient() external view returns (address);
5456
/// @notice Returns the current reserves of the pool
5557
/// @return reserve0 The amount of asset0 in the pool
5658
/// @return reserve1 The amount of asset1 in the pool

test/Fees.t.sol

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ contract FeesTest is EulerSwapTestBase {
5858

5959
// Holder's NAV increased by fee amount, plus slightly extra because we are not at curve equilibrium point
6060

61-
assertGt(getHolderNAV(), origNav + int256(amountIn - amountInNoFees));
62-
assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn);
61+
uint256 protocolFeesCollected = assetTST.balanceOf(address(0));
62+
63+
assertGt(getHolderNAV() + int256(protocolFeesCollected), origNav + int256(amountIn - amountInNoFees));
64+
assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn - protocolFeesCollected);
6365
assertEq(eTST2.balanceOf(address(holder)), 10e18 - amountOut);
6466
}
6567

@@ -107,8 +109,10 @@ contract FeesTest is EulerSwapTestBase {
107109

108110
// Holder's NAV increased by fee amount, plus slightly extra because we are not at curve equilibrium point
109111

110-
assertGt(getHolderNAV(), origNav + int256(amountIn - amountInNoFees));
111-
assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn);
112+
uint256 protocolFeesCollected = assetTST.balanceOf(address(0));
113+
114+
assertGt(getHolderNAV() + int256(protocolFeesCollected), origNav + int256(amountIn - amountInNoFees));
115+
assertEq(eTST.balanceOf(address(holder)), 10e18 + amountIn - protocolFeesCollected);
112116
assertEq(eTST2.balanceOf(address(holder)), 10e18 - amountOut);
113117
}
114118
}

0 commit comments

Comments
 (0)