@@ -4,7 +4,6 @@ pragma solidity ^0.8.22;
44import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol " ;
55import { IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol " ;
66import { IERC4626 } from "@openzeppelin/contracts/interfaces/IERC4626.sol " ;
7- import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol " ;
87
98import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol " ;
109
@@ -20,7 +19,6 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
2019 using OFTComposeMsgCodec for bytes ;
2120 using OFTComposeMsgCodec for bytes32 ;
2221 using SafeERC20 for IERC20 ;
23- using SafeERC20 for IERC20 ;
2422
2523 address public immutable ASSET_OFT; // any OFT
2624 address public immutable SHARE_OFT; // lockbox adapter
@@ -68,9 +66,6 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
6866 // Approve the shareOFTAdapter with the share tokens held by this contract
6967 IERC20 (IOFT (_shareOFT).token ()).approve (_shareOFT, type (uint256 ).max);
7068
71- ASSET_DECIMAL_CONVERSION_RATE = IOFT (_assetOFT).decimalConversionRate ();
72- SHARE_DECIMAL_CONVERSION_RATE = IOFT (_shareOFT).decimalConversionRate ();
73-
7469 REFUND_OVERPAY_ADDRESS = _refundOverpayAddress;
7570 ASSET_ERC20 = address (OVAULT.asset ());
7671 }
@@ -126,9 +121,9 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
126121 }
127122
128123 /// @dev Try to execute the action on the target OFT. If we hit an error then it rolls back the storage changes.
129- try this . executeOVaultActionWithSlippageCheck (_refundOFT, amount, sendParam.minAmountLD) returns (
130- uint256 vaultAmount
131- ) {
124+ try
125+ this . executeOVaultActionWithSlippageCheck (_refundOFT, sendParam.dstEid, amount, sendParam.minAmountLD)
126+ returns ( uint256 vaultAmount ) {
132127 /// @dev Setting the target amount to the actual value of the action (i.e. deposit or redeem)
133128 sendParam.amountLD = vaultAmount;
134129 } catch (bytes memory errMsg ) {
@@ -156,8 +151,15 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
156151 SendParam memory _sendParam ,
157152 address _refundAddress
158153 ) external payable nonReentrant {
154+ if (_sendParam.dstEid == HUB_EID && msg .value > 0 ) revert NoMsgValueOnSameChainOVaultAction ();
155+
159156 IERC20 (ASSET_ERC20).safeTransferFrom (msg .sender , address (this ), assetAmountLD);
160- _sendParam.amountLD = _executeOVaultActionWithSlippageCheck (ASSET_OFT, assetAmountLD, _sendParam.minAmountLD);
157+ _sendParam.amountLD = _executeOVaultActionWithSlippageCheck (
158+ ASSET_OFT,
159+ _sendParam.dstEid,
160+ assetAmountLD,
161+ _sendParam.minAmountLD
162+ );
161163 _send (SHARE_OFT, _sendParam, msg .value , _refundAddress);
162164 }
163165
@@ -166,8 +168,15 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
166168 SendParam memory _sendParam ,
167169 address _refundAddress
168170 ) external payable nonReentrant {
171+ if (_sendParam.dstEid == HUB_EID && msg .value > 0 ) revert NoMsgValueOnSameChainOVaultAction ();
172+
169173 IERC20 (OVAULT).safeTransferFrom (msg .sender , address (this ), shareAmountLD);
170- _sendParam.amountLD = _executeOVaultActionWithSlippageCheck (SHARE_OFT, shareAmountLD, _sendParam.minAmountLD);
174+ _sendParam.amountLD = _executeOVaultActionWithSlippageCheck (
175+ SHARE_OFT,
176+ _sendParam.dstEid,
177+ shareAmountLD,
178+ _sendParam.minAmountLD
179+ );
171180 _send (ASSET_OFT, _sendParam, msg .value , _refundAddress);
172181 }
173182
@@ -195,12 +204,13 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
195204 /// @dev External call for try...catch logic in lzCompose()
196205 function executeOVaultActionWithSlippageCheck (
197206 address _refundOFT ,
207+ uint32 _dstEid ,
198208 uint256 _amount ,
199209 uint256 _minAmountLD
200210 ) external nonReentrant returns (uint256 vaultAmount ) {
201211 if (msg .sender != address (this )) revert OnlySelf (msg .sender );
202212
203- vaultAmount = _executeOVaultActionWithSlippageCheck (_refundOFT, _amount, _minAmountLD);
213+ vaultAmount = _executeOVaultActionWithSlippageCheck (_refundOFT, _dstEid, _amount, _minAmountLD);
204214 }
205215
206216 /// @dev External call for try...catch logic in lzCompose()
@@ -212,7 +222,7 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
212222 address _receiver = _sendParam.to.bytes32ToAddress ();
213223 uint256 _amountLD = _sendParam.amountLD;
214224 IERC20 token = IERC20 (IOFT (_oft).token ());
215- token.transfer (_receiver, _amountLD);
225+ token.safeTransfer (_receiver, _amountLD);
216226 if (msg .value > 0 ) {
217227 (bool sent , ) = _receiver.call { value: msg .value }("" );
218228 require (sent, "Failed to send Ether " );
@@ -249,7 +259,6 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
249259 function retry (bytes32 _guid , bool _removeExtraOptions ) external payable nonReentrant {
250260 FailedMessage memory failedMessage = failedMessages[_guid];
251261 if (_failedGuidState (failedMessage) != FailedState.CanOnlyRetry) revert CanNotRetry (_guid);
252- if (_failedGuidState (failedMessage) != FailedState.CanOnlyRetry) revert CanNotRetry (_guid);
253262
254263 SendParam memory sendParam = failedMessage.sendParam;
255264 uint256 prepaidMsgValue = failedMessage.msgValue;
@@ -277,6 +286,7 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
277286
278287 failedMessage.sendParam.amountLD = _executeOVaultActionWithSlippageCheck (
279288 failedMessage.refundOFT,
289+ failedMessage.sendParam.dstEid, //dstEid
280290 failedMessage.refundSendParam.amountLD,
281291 failedMessage.sendParam.minAmountLD
282292 );
@@ -327,12 +337,13 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
327337
328338 function _executeOVaultActionWithSlippageCheck (
329339 address _refundOFT ,
340+ uint32 _dstEid ,
330341 uint256 _amount ,
331342 uint256 _minAmountLD
332343 ) internal returns (uint256 ) {
333344 (uint256 vaultAmount , address targetOFT ) = _executeOVaultAction (_refundOFT, _amount);
334345
335- _checkSlippage (targetOFT, vaultAmount, _minAmountLD);
346+ _checkSlippage (targetOFT, _dstEid, vaultAmount, _minAmountLD);
336347
337348 return vaultAmount;
338349 }
@@ -396,8 +407,10 @@ contract OVaultComposer is IOVaultComposer, ReentrancyGuard {
396407 /// @dev Remove dust before slippage check to be equivalent to OFTCore::_debitView()
397408 /// @dev If the OFT has a Fee or anything that changes the tokens such that:
398409 /// @dev dstChain.receivedAmount != srcChain.sentAmount, this will have to be overridden.
399- function _checkSlippage (address _oft , uint256 _amount , uint256 _minAmountLD ) internal view virtual {
400- uint256 vaultAmountLD = _removeDust (_oft, _amount);
410+ function _checkSlippage (address _oft , uint32 _dstEid , uint256 _amount , uint256 _minAmountLD ) internal view virtual {
411+ /// @dev In the event of a same chain deposit. Dust is never removed since we do not call OFT.send() but ERC20.transfer()
412+ uint256 vaultAmountLD = HUB_EID == _dstEid ? _amount : _removeDust (_oft, _amount);
413+
401414 uint256 amountReceivedLD = vaultAmountLD; /// @dev Perform your adjustments here if needed (ex: Fee)
402415 if (amountReceivedLD < _minAmountLD) {
403416 revert NotEnoughTargetTokens (amountReceivedLD, _minAmountLD);
0 commit comments