Skip to content

Commit 53a268d

Browse files
authored
fix: Use per destination fees for Everclear bridge (#7091)
1 parent 5b17b0f commit 53a268d

File tree

5 files changed

+105
-82
lines changed

5 files changed

+105
-82
lines changed

solidity/contracts/token/bridge/EverclearEthBridge.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ contract EverclearEthBridge is EverclearTokenBridge {
7474
quotes[0] = Quote({
7575
token: address(0),
7676
amount: _amount +
77-
feeParams.fee +
77+
feeParams[_destination].fee +
7878
_quoteGasPayment(_destination, _recipient, _amount)
7979
});
8080
}
@@ -124,7 +124,7 @@ contract EverclearEthBridge is EverclearTokenBridge {
124124
) internal virtual override returns (uint256 dispatchValue) {
125125
uint256 fee = _feeAmount(_destination, _recipient, _amount);
126126

127-
uint256 totalAmount = _amount + fee + feeParams.fee;
127+
uint256 totalAmount = _amount + fee + feeParams[_destination].fee;
128128
_transferFromSender(totalAmount);
129129
dispatchValue = msg.value - totalAmount;
130130
if (fee > 0) {

solidity/contracts/token/bridge/EverclearTokenBridge.sol

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,28 @@ contract EverclearTokenBridge is HypERC20Collateral {
3434
using TypeCasts for bytes32;
3535
using SafeERC20 for IERC20;
3636

37+
/// @notice Parameters for creating an Everclear intent
38+
/// @dev This is used to avoid stack too deep errors
39+
struct IntentParams {
40+
bytes32 receiver;
41+
address inputAsset;
42+
bytes32 outputAsset;
43+
uint256 amount;
44+
IEverclearAdapter.FeeParams feeParams;
45+
}
46+
3747
/// @notice The output asset for a given destination domain
3848
/// @dev Everclear needs to know the output asset address to create intents for cross-chain transfers
39-
mapping(uint32 destination => bytes32 outputAssets) public outputAssets;
49+
mapping(uint32 destination => bytes32 outputAsset) public outputAssets;
4050

4151
/// @notice Whether an intent has been settled
4252
/// @dev This is used to prevent funds from being sent to a recipient that has already received them
4353
mapping(bytes32 intentId => bool isSettled) public intentSettled;
4454

4555
/// @notice Fee parameters for the bridge operations
4656
/// @dev The signatures are produced by Everclear and stored here for re-use. We use the same fee for all transfers to all destinations
47-
IEverclearAdapter.FeeParams public feeParams;
57+
mapping(uint32 destination => IEverclearAdapter.FeeParams feeParams)
58+
public feeParams;
4859

4960
/// @notice The Everclear adapter contract interface
5061
/// @dev Immutable reference to the Everclear adapter used for creating intents
@@ -58,7 +69,7 @@ contract EverclearTokenBridge is HypERC20Collateral {
5869
* @param fee The new fee amount
5970
* @param deadline The new deadline timestamp for fee validity
6071
*/
61-
event FeeParamsUpdated(uint256 fee, uint256 deadline);
72+
event FeeParamsUpdated(uint32 destination, uint256 fee, uint256 deadline);
6273

6374
/**
6475
* @notice Emitted when an output asset is configured for a destination
@@ -103,16 +114,17 @@ contract EverclearTokenBridge is HypERC20Collateral {
103114
* @param _sig The signature for fee validation from Everclear
104115
*/
105116
function setFeeParams(
117+
uint32 _destination,
106118
uint256 _fee,
107119
uint256 _deadline,
108120
bytes calldata _sig
109121
) external onlyOwner {
110-
feeParams = IEverclearAdapter.FeeParams({
122+
feeParams[_destination] = IEverclearAdapter.FeeParams({
111123
fee: _fee,
112124
deadline: _deadline,
113125
sig: _sig
114126
});
115-
emit FeeParamsUpdated(_fee, _deadline);
127+
emit FeeParamsUpdated(_destination, _fee, _deadline);
116128
}
117129

118130
/**
@@ -179,7 +191,7 @@ contract EverclearTokenBridge is HypERC20Collateral {
179191
});
180192
quotes[1] = Quote({
181193
token: address(wrappedToken),
182-
amount: _amount + feeParams.fee
194+
amount: _amount + feeParams[_destination].fee
183195
});
184196
}
185197

@@ -200,22 +212,35 @@ contract EverclearTokenBridge is HypERC20Collateral {
200212
outputAssets[_destination] != bytes32(0),
201213
"ETB: Output asset not set"
202214
);
215+
require(
216+
feeParams[_destination].sig.length > 0,
217+
"ETB: Fee params not set"
218+
);
203219

204220
// Create everclear intent
205221
uint32[] memory destinations = new uint32[](1);
206222
destinations[0] = _destination;
207223

208224
// Create intent
225+
// Packing the intent params in a struct to avoid stack too deep errors
226+
IntentParams memory intentParams = IntentParams({
227+
feeParams: feeParams[_destination],
228+
receiver: _getReceiver(_destination, _recipient),
229+
inputAsset: address(wrappedToken),
230+
outputAsset: outputAssets[_destination],
231+
amount: _amount
232+
});
233+
209234
(, IEverclear.Intent memory intent) = everclearAdapter.newIntent({
210235
_destinations: destinations,
211-
_receiver: _getReceiver(_destination, _recipient),
212-
_inputAsset: address(wrappedToken),
213-
_outputAsset: outputAssets[_destination], // We load this from storage again to avoid stack too deep
214-
_amount: _amount,
236+
_receiver: intentParams.receiver,
237+
_inputAsset: intentParams.inputAsset,
238+
_outputAsset: intentParams.outputAsset,
239+
_amount: intentParams.amount,
215240
_maxFee: 0,
216241
_ttl: 0,
217242
_data: "",
218-
_feeParams: feeParams
243+
_feeParams: intentParams.feeParams
219244
});
220245

221246
return intent;
@@ -253,7 +278,7 @@ contract EverclearTokenBridge is HypERC20Collateral {
253278
super._chargeSender(
254279
_destination,
255280
_recipient,
256-
_amount + feeParams.fee
281+
_amount + feeParams[_destination].fee
257282
);
258283
}
259284

solidity/foundry.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ cache_path = 'forge-cache'
88
allow_paths = ["../node_modules"]
99
solc_version = '0.8.22'
1010
evm_version= 'paris'
11-
# optimizer = true
1211
optimizer_runs = 999_999
1312
fs_permissions = [
1413
{ access = "read", path = "./script/avs/"},

solidity/script/EverclearTokenBridge.s.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ contract EverclearTokenBridgeScript is Script {
3838

3939
// Set the fee params for the bridge.
4040
bridge.setFeeParams(
41+
10, // destination domain
4142
1000000000000,
4243
1751851366,
4344
hex"4edddfdeabc459e3e9df4bc6807698e26443a663b3905c9b5d0f1054b4831b4616e89ff702f57e13d650331f11986ebe925ce497621b7f488c4672189b49b8e11c"
@@ -50,7 +51,7 @@ contract EverclearTokenBridgeScript is Script {
5051
EverclearTokenBridge bridge = _getBridge();
5152

5253
// Convert some eth to weth
53-
(uint256 fee, , ) = bridge.feeParams();
54+
(uint256 fee, , ) = bridge.feeParams(10); // destination domain 10 (Optimism)
5455
uint256 amount = 0.0001 ether;
5556
uint256 totalAmount = amount + fee + 1;
5657
IWETH weth = IWETH(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1);

0 commit comments

Comments
 (0)