From fd94eb9a1886c26cbe2ab792e3a643ffdaa9bfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Mon, 6 Nov 2023 15:40:10 -0800 Subject: [PATCH 01/12] Adding in update to NativeOFTWithFee --- .../token/oft/v2/fee/NativeOFTWithFee.sol | 15 +++++++ test/oft/v2/NativeOFTWithFee.test.js | 42 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index 0f5e7e8a..c38abf0c 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -25,6 +25,21 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { emit Withdrawal(msg.sender, _amount); } + /************************************************************************ + * public functions + ************************************************************************/ + function sendFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, LzCallParams calldata _callParams) public payable virtual override { + _amount = _send(_from, _dstChainId, _toAddress, _amount, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams); + (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); + require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); + } + + function sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams) public payable virtual override { + _amount = _sendAndCall(_from, _dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams); + (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); + require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); + } + function _send(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual override returns (uint amount) { _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS); diff --git a/test/oft/v2/NativeOFTWithFee.test.js b/test/oft/v2/NativeOFTWithFee.test.js index 5a7b7fbd..156c8654 100644 --- a/test/oft/v2/NativeOFTWithFee.test.js +++ b/test/oft/v2/NativeOFTWithFee.test.js @@ -133,6 +133,48 @@ describe("NativeOFTWithFee: ", function () { expect(await remoteOFTWithFee.balanceOf(owner.address)).to.equal(0) expect(await ethers.provider.getBalance(nativeOFTWithFee.address)).to.equal(0) + let leftOverAmount = ethers.utils.parseEther("0") + let totalAmount = ethers.utils.parseEther("8") + + expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(0) + expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(0) + expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(0) + expect(await remoteOFTWithFee.balanceOf(owner.address)).to.be.equal(0) + + const aliceAddressBytes32 = ethers.utils.defaultAbiCoder.encode(["address"], [alice.address]) + // estimate nativeFees + let fee = await nativeOFTWithFee.quoteOFTFee(remoteChainId, totalAmount) + let nativeFee = (await nativeOFTWithFee.estimateSendFee(remoteChainId, aliceAddressBytes32, totalAmount, false, defaultAdapterParams)) + .nativeFee + await nativeOFTWithFee.sendFrom( + owner.address, + remoteChainId, // destination chainId + aliceAddressBytes32, // destination address to send tokens to + totalAmount, // quantity of tokens to send (in units of wei) + totalAmount.sub(fee), // quantity of tokens to send (in units of wei) + [owner.address, ethers.constants.AddressZero, defaultAdapterParams], + { value: nativeFee.add(totalAmount) } // pass a msg.value to pay the LayerZero message fee + ) + expect(await ethers.provider.getBalance(nativeOFTWithFee.address)).to.be.equal(totalAmount) + expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(nativeFee) // collects + expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(leftOverAmount) + expect(await nativeOFTWithFee.balanceOf(alice.address)).to.be.equal(leftOverAmount) + expect(await nativeOFTWithFee.balanceOf(bob.address)).to.be.equal(fee) + expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalAmount.sub(fee)) + }) + + it("sendFrom() w/ fee change - deposit before send", async function () { + expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(ethers.utils.parseEther("0")) + + // set default fee to 50% + await nativeOFTWithFee.setDefaultFeeBp(5000) + await nativeOFTWithFee.setFeeOwner(bob.address) + + // ensure they're both allocated initial amounts + expect(await nativeOFTWithFee.balanceOf(owner.address)).to.equal(0) + expect(await remoteOFTWithFee.balanceOf(owner.address)).to.equal(0) + expect(await ethers.provider.getBalance(nativeOFTWithFee.address)).to.equal(0) + let depositAmount = ethers.utils.parseEther("7") await nativeOFTWithFee.deposit({ value: depositAmount }) From 5d50cc8e2e32115267211c0ff92a2e61cb990e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 10:13:24 -0800 Subject: [PATCH 02/12] updating logic with fee for native --- .../token/oft/v2/fee/NativeOFTWithFee.sol | 26 +++++++++++++------ test/oft/v2/NativeOFTWithFee.test.js | 3 +-- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index c38abf0c..fc5f9f1a 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -30,22 +30,26 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { ************************************************************************/ function sendFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, LzCallParams calldata _callParams) public payable virtual override { _amount = _send(_from, _dstChainId, _toAddress, _amount, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams); - (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); } function sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams) public payable virtual override { _amount = _sendAndCall(_from, _dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams); - (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); } function _send(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual override returns (uint amount) { _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS); - (amount,) = _removeDust(_amount); - require(amount > 0, "NativeOFTWithFee: amount too small"); - uint messageFee = _debitFromNative(_from, amount); + require(_amount > 0, "NativeOFTWithFee: amount too small"); + uint messageFee = _debitFromNative(_from, _amount); + (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); + + uint dust; + (amount, dust) = _removeDust(_amount); + if(dust > 0) { + _transferFrom(address(this), _from, dust); + } bytes memory lzPayload = _encodeSendPayload(_toAddress, _ld2sd(amount)); _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, messageFee); @@ -56,9 +60,15 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { function _sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes memory _payload, uint64 _dstGasForCall, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual override returns (uint amount) { _checkGasLimit(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall); - (amount,) = _removeDust(_amount); - require(amount > 0, "NativeOFTWithFee: amount too small"); - uint messageFee = _debitFromNative(_from, amount); + require(_amount > 0, "NativeOFTWithFee: amount too small"); + uint messageFee = _debitFromNative(_from, _amount); + (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); + + uint dust; + (amount, dust) = _removeDust(_amount); + if(dust > 0) { + _transferFrom(address(this), _from, dust); + } // encode the msg.sender into the payload instead of _from bytes memory lzPayload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(amount), _payload, _dstGasForCall); diff --git a/test/oft/v2/NativeOFTWithFee.test.js b/test/oft/v2/NativeOFTWithFee.test.js index 156c8654..107ff4b8 100644 --- a/test/oft/v2/NativeOFTWithFee.test.js +++ b/test/oft/v2/NativeOFTWithFee.test.js @@ -125,7 +125,7 @@ describe("NativeOFTWithFee: ", function () { expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(ethers.utils.parseEther("0")) // set default fee to 50% - await nativeOFTWithFee.setDefaultFeeBp(5000) + await nativeOFTWithFee.setDefaultFeeBp(1) await nativeOFTWithFee.setFeeOwner(bob.address) // ensure they're both allocated initial amounts @@ -155,7 +155,6 @@ describe("NativeOFTWithFee: ", function () { [owner.address, ethers.constants.AddressZero, defaultAdapterParams], { value: nativeFee.add(totalAmount) } // pass a msg.value to pay the LayerZero message fee ) - expect(await ethers.provider.getBalance(nativeOFTWithFee.address)).to.be.equal(totalAmount) expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(nativeFee) // collects expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(leftOverAmount) expect(await nativeOFTWithFee.balanceOf(alice.address)).to.be.equal(leftOverAmount) From 6cf68e071379d961c57698cc17a2db5a05482a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 12:30:43 -0800 Subject: [PATCH 03/12] update --- .../token/oft/v2/fee/NativeOFTWithFee.sol | 58 ++++++++++--------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index fc5f9f1a..b52af7f3 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -42,14 +42,8 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS); require(_amount > 0, "NativeOFTWithFee: amount too small"); - uint messageFee = _debitFromNative(_from, _amount); - (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); - - uint dust; - (amount, dust) = _removeDust(_amount); - if(dust > 0) { - _transferFrom(address(this), _from, dust); - } + uint messageFee; + (messageFee, amount) = _debitFromNative(_from, _amount, _dstChainId); bytes memory lzPayload = _encodeSendPayload(_toAddress, _ld2sd(amount)); _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, messageFee); @@ -61,14 +55,8 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { _checkGasLimit(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall); require(_amount > 0, "NativeOFTWithFee: amount too small"); - uint messageFee = _debitFromNative(_from, _amount); - (_amount,) = _payOFTFee(address(this), _dstChainId, _amount); - - uint dust; - (amount, dust) = _removeDust(_amount); - if(dust > 0) { - _transferFrom(address(this), _from, dust); - } + uint messageFee; + (messageFee, amount) = _debitFromNative(_from, _amount, _dstChainId); // encode the msg.sender into the payload instead of _from bytes memory lzPayload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(amount), _payload, _dstGasForCall); @@ -77,35 +65,53 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { emit SendToChain(_dstChainId, _from, _toAddress, amount); } - function _debitFromNative(address _from, uint _amount) internal returns (uint messageFee) { - messageFee = msg.sender == _from ? _debitMsgSender(_amount) : _debitMsgFrom(_from, _amount); + function _debitFromNative(address _from, uint _amount, uint16 _dstChainId) internal returns (uint messageFee, uint amount) { + uint fee = quoteOFTFee(_dstChainId, _amount); + + // subtract fee from _amount + _amount -= fee; + + // pay fee and update newMsgValue + uint newMsgValue; + if(balanceOf(_from) > fee) { + _transferFrom(_from, feeOwner, fee); + newMsgValue = msg.value; + } else { + _mint(feeOwner, fee); + newMsgValue = msg.value - fee; + } + + (amount,) = _removeDust(_amount); + require(amount > 0, "NativeOFTWithFee: amount too small"); + messageFee = msg.sender == _from ? _debitMsgSender(amount, newMsgValue) : _debitMsgFrom(_from, amount, newMsgValue); } - function _debitMsgSender(uint _amount) internal returns (uint messageFee) { + function _debitMsgSender(uint _amount, uint currentMsgValue) internal returns (uint messageFee) { uint msgSenderBalance = balanceOf(msg.sender); if (msgSenderBalance < _amount) { - require(msgSenderBalance + msg.value >= _amount, "NativeOFTWithFee: Insufficient msg.value"); + require(msgSenderBalance + currentMsgValue >= _amount, "NativeOFTWithFee: Insufficient msg.value"); // user can cover difference with additional msg.value ie. wrapping uint mintAmount = _amount - msgSenderBalance; + _mint(address(msg.sender), mintAmount); // update the messageFee to take out mintAmount - messageFee = msg.value - mintAmount; + messageFee = currentMsgValue - mintAmount; } else { - messageFee = msg.value; + messageFee = currentMsgValue; } _transfer(msg.sender, address(this), _amount); return messageFee; } - function _debitMsgFrom(address _from, uint _amount) internal returns (uint messageFee) { + function _debitMsgFrom(address _from, uint _amount, uint currentMsgValue) internal returns (uint messageFee) { uint msgFromBalance = balanceOf(_from); if (msgFromBalance < _amount) { - require(msgFromBalance + msg.value >= _amount, "NativeOFTWithFee: Insufficient msg.value"); + require(msgFromBalance + currentMsgValue >= _amount, "NativeOFTWithFee: Insufficient msg.value"); // user can cover difference with additional msg.value ie. wrapping uint mintAmount = _amount - msgFromBalance; @@ -118,9 +124,9 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { _amount = msgFromBalance; // update the messageFee to take out mintAmount - messageFee = msg.value - mintAmount; + messageFee = currentMsgValue - mintAmount; } else { - messageFee = msg.value; + messageFee = currentMsgValue; } _spendAllowance(_from, msg.sender, _amount); From aae82d201d9874081ebb22a5ec207bf0b12e457f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 13:00:00 -0800 Subject: [PATCH 04/12] remove duplicate check --- contracts/token/oft/v2/fee/NativeOFTWithFee.sol | 2 -- 1 file changed, 2 deletions(-) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index b52af7f3..f498fd04 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -41,7 +41,6 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { function _send(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual override returns (uint amount) { _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS); - require(_amount > 0, "NativeOFTWithFee: amount too small"); uint messageFee; (messageFee, amount) = _debitFromNative(_from, _amount, _dstChainId); @@ -54,7 +53,6 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { function _sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes memory _payload, uint64 _dstGasForCall, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual override returns (uint amount) { _checkGasLimit(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall); - require(_amount > 0, "NativeOFTWithFee: amount too small"); uint messageFee; (messageFee, amount) = _debitFromNative(_from, _amount, _dstChainId); From 5860b655f45398d21400c87265dcd3dc2ab2caf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 13:20:27 -0800 Subject: [PATCH 05/12] refactor --- .../token/oft/v2/fee/NativeOFTWithFee.sol | 25 +++++----- test/oft/v2/NativeOFTWithFee.test.js | 47 +++++++++++++++++++ 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index f498fd04..41f4c0e2 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -65,18 +65,19 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { function _debitFromNative(address _from, uint _amount, uint16 _dstChainId) internal returns (uint messageFee, uint amount) { uint fee = quoteOFTFee(_dstChainId, _amount); - - // subtract fee from _amount - _amount -= fee; - - // pay fee and update newMsgValue - uint newMsgValue; - if(balanceOf(_from) > fee) { - _transferFrom(_from, feeOwner, fee); - newMsgValue = msg.value; - } else { - _mint(feeOwner, fee); - newMsgValue = msg.value - fee; + uint newMsgValue = msg.value; + + if(fee > 0) { + // subtract fee from _amount + _amount -= fee; + + // pay fee and update newMsgValue + if(balanceOf(_from) >= fee) { + _transferFrom(_from, feeOwner, fee); + } else { + _mint(feeOwner, fee); + newMsgValue = msg.value - fee; + } } (amount,) = _removeDust(_amount); diff --git a/test/oft/v2/NativeOFTWithFee.test.js b/test/oft/v2/NativeOFTWithFee.test.js index 107ff4b8..49e117f5 100644 --- a/test/oft/v2/NativeOFTWithFee.test.js +++ b/test/oft/v2/NativeOFTWithFee.test.js @@ -162,6 +162,53 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalAmount.sub(fee)) }) + it("sendFrom() w/ fee change - tokens from main to other chain without taking dust", async function () { + expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(ethers.utils.parseEther("0")) + + // set default fee to 50% + await nativeOFTWithFee.setDefaultFeeBp(1) + await nativeOFTWithFee.setFeeOwner(bob.address) + + // ensure they're both allocated initial amounts + expect(await nativeOFTWithFee.balanceOf(owner.address)).to.equal(0) + expect(await remoteOFTWithFee.balanceOf(owner.address)).to.equal(0) + expect(await ethers.provider.getBalance(nativeOFTWithFee.address)).to.equal(0) + + let leftOverAmount = ethers.utils.parseEther("0") + let totalAmount = ethers.utils.parseEther("8.123456789") + + expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(0) + expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(0) + expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(0) + expect(await remoteOFTWithFee.balanceOf(owner.address)).to.be.equal(0) + + const aliceAddressBytes32 = ethers.utils.defaultAbiCoder.encode(["address"], [alice.address]) + // estimate nativeFees + let fee = await nativeOFTWithFee.quoteOFTFee(remoteChainId, totalAmount) + let nativeFee = (await nativeOFTWithFee.estimateSendFee(remoteChainId, aliceAddressBytes32, totalAmount, false, defaultAdapterParams)) + .nativeFee + + + let ld2sdRate = 10 ** (18 - sharedDecimals) + let dust = totalAmount.sub(fee).mod(ld2sdRate) + let totalMintAmount = (totalAmount.sub(fee)).sub(dust) + + await nativeOFTWithFee.sendFrom( + owner.address, + remoteChainId, // destination chainId + aliceAddressBytes32, // destination address to send tokens to + totalAmount, // quantity of tokens to send (in units of wei) + totalMintAmount, // quantity of tokens to send (in units of wei) + [owner.address, ethers.constants.AddressZero, defaultAdapterParams], + { value: nativeFee.add(totalAmount) } // pass a msg.value to pay the LayerZero message fee + ) + expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(nativeFee) // collects + expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(leftOverAmount) + expect(await nativeOFTWithFee.balanceOf(bob.address)).to.be.equal(fee) + expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalMintAmount) + expect(await remoteOFTWithFee.balanceOf(alice.address)).to.be.equal(totalMintAmount) + }) + it("sendFrom() w/ fee change - deposit before send", async function () { expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(ethers.utils.parseEther("0")) From 5bc2958b8e40e1fb127d2a7ace736ae652f3c0cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 13:23:34 -0800 Subject: [PATCH 06/12] minor refactor --- contracts/token/oft/v2/fee/NativeOFTWithFee.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index 41f4c0e2..1f11a96a 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -76,7 +76,7 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { _transferFrom(_from, feeOwner, fee); } else { _mint(feeOwner, fee); - newMsgValue = msg.value - fee; + newMsgValue -= fee; } } From 920b72342eed2c47765091f1ee2ad82a4789fb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 17:31:58 -0800 Subject: [PATCH 07/12] adding in outboundAmount --- contracts/token/oft/v2/fee/NativeOFTWithFee.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index 1f11a96a..efe270a8 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -7,6 +7,8 @@ import "./OFTWithFee.sol"; contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { + uint public outboundAmount; + event Deposit(address indexed _dst, uint _amount); event Withdrawal(address indexed _src, uint _amount); @@ -103,6 +105,7 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { } _transfer(msg.sender, address(this), _amount); + outboundAmount += _amount; return messageFee; } @@ -130,10 +133,12 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { _spendAllowance(_from, msg.sender, _amount); _transfer(_from, address(this), _amount); + outboundAmount += _amount; return messageFee; } function _creditTo(uint16, address _toAddress, uint _amount) internal override returns(uint) { + outboundAmount -= _amount; _burn(address(this), _amount); (bool success, ) = _toAddress.call{value: _amount}(""); require(success, "NativeOFTWithFee: failed to _creditTo"); From 5c1632d9b7fc4e8b058cc5bbb7fdb06b51714c5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 17:46:24 -0800 Subject: [PATCH 08/12] adding outboundAmount to NativeOFTV2 and NativeOFTWithFee --- contracts/token/oft/v2/NativeOFTV2.sol | 5 +++++ contracts/token/oft/v2/fee/NativeOFTWithFee.sol | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/contracts/token/oft/v2/NativeOFTV2.sol b/contracts/token/oft/v2/NativeOFTV2.sol index 4db4c04d..76a067b2 100644 --- a/contracts/token/oft/v2/NativeOFTV2.sol +++ b/contracts/token/oft/v2/NativeOFTV2.sol @@ -6,6 +6,8 @@ import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./OFTV2.sol"; contract NativeOFTV2 is OFTV2, ReentrancyGuard { + uint public outboundAmount; + event Deposit(address indexed _dst, uint _amount); event Withdrawal(address indexed _src, uint _amount); @@ -115,6 +117,7 @@ contract NativeOFTV2 is OFTV2, ReentrancyGuard { function _debitMsgSender(uint _amount) internal returns (uint messageFee) { uint msgSenderBalance = balanceOf(msg.sender); + outboundAmount += _amount; if (msgSenderBalance < _amount) { require(msgSenderBalance + msg.value >= _amount, "NativeOFTV2: Insufficient msg.value"); @@ -135,6 +138,7 @@ contract NativeOFTV2 is OFTV2, ReentrancyGuard { function _debitMsgFrom(address _from, uint _amount) internal returns (uint messageFee) { uint msgFromBalance = balanceOf(_from); + outboundAmount += _amount; if (msgFromBalance < _amount) { require(msgFromBalance + msg.value >= _amount, "NativeOFTV2: Insufficient msg.value"); @@ -165,6 +169,7 @@ contract NativeOFTV2 is OFTV2, ReentrancyGuard { address _toAddress, uint _amount ) internal override returns (uint) { + outboundAmount -= _amount; _burn(address(this), _amount); (bool success, ) = _toAddress.call{value: _amount}(""); require(success, "NativeOFTV2: failed to _creditTo"); diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index efe270a8..0d9cf62c 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -6,7 +6,6 @@ import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./OFTWithFee.sol"; contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { - uint public outboundAmount; event Deposit(address indexed _dst, uint _amount); @@ -89,6 +88,7 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { function _debitMsgSender(uint _amount, uint currentMsgValue) internal returns (uint messageFee) { uint msgSenderBalance = balanceOf(msg.sender); + outboundAmount += _amount; if (msgSenderBalance < _amount) { require(msgSenderBalance + currentMsgValue >= _amount, "NativeOFTWithFee: Insufficient msg.value"); @@ -105,12 +105,12 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { } _transfer(msg.sender, address(this), _amount); - outboundAmount += _amount; return messageFee; } function _debitMsgFrom(address _from, uint _amount, uint currentMsgValue) internal returns (uint messageFee) { uint msgFromBalance = balanceOf(_from); + outboundAmount += _amount; if (msgFromBalance < _amount) { require(msgFromBalance + currentMsgValue >= _amount, "NativeOFTWithFee: Insufficient msg.value"); @@ -133,7 +133,6 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { _spendAllowance(_from, msg.sender, _amount); _transfer(_from, address(this), _amount); - outboundAmount += _amount; return messageFee; } From 4dd9abe212b2f2959942ede2ebbd01f16653a11c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 18:09:30 -0800 Subject: [PATCH 09/12] adding in unit test --- contracts/token/oft/v2/NativeOFTV2.sol | 3 +-- .../token/oft/v2/fee/NativeOFTWithFee.sol | 3 +-- test/oft/v2/NativeOFTV2.test.js | 11 +++++++++++ test/oft/v2/NativeOFTWithFee.test.js | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/contracts/token/oft/v2/NativeOFTV2.sol b/contracts/token/oft/v2/NativeOFTV2.sol index 76a067b2..9e84fab3 100644 --- a/contracts/token/oft/v2/NativeOFTV2.sol +++ b/contracts/token/oft/v2/NativeOFTV2.sol @@ -112,12 +112,12 @@ contract NativeOFTV2 is OFTV2, ReentrancyGuard { } function _debitFromNative(address _from, uint _amount) internal returns (uint messageFee) { + outboundAmount += _amount; messageFee = msg.sender == _from ? _debitMsgSender(_amount) : _debitMsgFrom(_from, _amount); } function _debitMsgSender(uint _amount) internal returns (uint messageFee) { uint msgSenderBalance = balanceOf(msg.sender); - outboundAmount += _amount; if (msgSenderBalance < _amount) { require(msgSenderBalance + msg.value >= _amount, "NativeOFTV2: Insufficient msg.value"); @@ -138,7 +138,6 @@ contract NativeOFTV2 is OFTV2, ReentrancyGuard { function _debitMsgFrom(address _from, uint _amount) internal returns (uint messageFee) { uint msgFromBalance = balanceOf(_from); - outboundAmount += _amount; if (msgFromBalance < _amount) { require(msgFromBalance + msg.value >= _amount, "NativeOFTV2: Insufficient msg.value"); diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index 0d9cf62c..88e37ebc 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -83,12 +83,12 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { (amount,) = _removeDust(_amount); require(amount > 0, "NativeOFTWithFee: amount too small"); + outboundAmount += amount; messageFee = msg.sender == _from ? _debitMsgSender(amount, newMsgValue) : _debitMsgFrom(_from, amount, newMsgValue); } function _debitMsgSender(uint _amount, uint currentMsgValue) internal returns (uint messageFee) { uint msgSenderBalance = balanceOf(msg.sender); - outboundAmount += _amount; if (msgSenderBalance < _amount) { require(msgSenderBalance + currentMsgValue >= _amount, "NativeOFTWithFee: Insufficient msg.value"); @@ -110,7 +110,6 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { function _debitMsgFrom(address _from, uint _amount, uint currentMsgValue) internal returns (uint messageFee) { uint msgFromBalance = balanceOf(_from); - outboundAmount += _amount; if (msgFromBalance < _amount) { require(msgFromBalance + currentMsgValue >= _amount, "NativeOFTWithFee: Insufficient msg.value"); diff --git a/test/oft/v2/NativeOFTV2.test.js b/test/oft/v2/NativeOFTV2.test.js index 253f5a20..b991a313 100644 --- a/test/oft/v2/NativeOFTV2.test.js +++ b/test/oft/v2/NativeOFTV2.test.js @@ -86,6 +86,9 @@ describe("NativeOFTV2: ", function () { expect(await nativeOFTV2.balanceOf(nativeOFTV2.address)).to.be.equal(totalAmount) expect(await nativeOFTV2.balanceOf(owner.address)).to.be.equal(leftOverAmount) expect(await remoteOFTV2.balanceOf(owner.address)).to.be.equal(totalAmount) + expect(await nativeOFTV2.outboundAmount()).to.be.equal(totalAmount) + expect(await remoteOFTV2.totalSupply()).to.be.equal(totalAmount) + let ownerBalance2 = await ethers.provider.getBalance(owner.address) @@ -106,6 +109,8 @@ describe("NativeOFTV2: ", function () { expect(await ethers.provider.getBalance(owner.address)).to.be.equal(ownerBalance2.sub(nativeFee).sub(transFee)) expect(await nativeOFTV2.balanceOf(owner.address)).to.equal(leftOverAmount) expect(await remoteOFTV2.balanceOf(owner.address)).to.equal(0) + expect(await remoteOFTV2.totalSupply()).to.be.equal(leftOverAmount) + expect(await nativeOFTV2.outboundAmount()).to.be.equal(leftOverAmount) }) it("sendFrom() - with enough native", async function () { @@ -142,6 +147,8 @@ describe("NativeOFTV2: ", function () { expect(await nativeOFTV2.balanceOf(nativeOFTV2.address)).to.be.equal(totalAmountMinusDust) expect(await nativeOFTV2.balanceOf(owner.address)).to.be.equal(leftOverAmount) expect(await remoteOFTV2.balanceOf(owner.address)).to.be.equal(totalAmountMinusDust) + expect(await nativeOFTV2.outboundAmount()).to.be.equal(totalAmountMinusDust) + expect(await remoteOFTV2.totalSupply()).to.be.equal(totalAmountMinusDust) }) it("sendFrom() - from != sender with addition msg.value", async function () { @@ -180,6 +187,8 @@ describe("NativeOFTV2: ", function () { expect(await nativeOFTV2.balanceOf(nativeOFTV2.address)).to.be.equal(totalAmount) expect(await nativeOFTV2.balanceOf(owner.address)).to.be.equal(leftOverAmount) expect(await remoteOFTV2.balanceOf(owner.address)).to.be.equal(totalAmount) + expect(await nativeOFTV2.outboundAmount()).to.be.equal(totalAmount) + expect(await remoteOFTV2.totalSupply()).to.be.equal(totalAmount) }) it("sendFrom() - from != sender with not enough native", async function () { @@ -286,6 +295,8 @@ describe("NativeOFTV2: ", function () { // verify tokens burned on source chain and minted on destination chain expect(await nativeOFTV2.balanceOf(nativeOFTV2.address)).to.be.equal(amount) expect(await remoteOFTV2.balanceOf(owner.address)).to.be.equal(amount) + expect(await nativeOFTV2.outboundAmount()).to.be.equal(amount) + expect(await remoteOFTV2.totalSupply()).to.be.equal(amount) }) it("setMinDstGas() - when type is not set on destination chain", async function () { diff --git a/test/oft/v2/NativeOFTWithFee.test.js b/test/oft/v2/NativeOFTWithFee.test.js index 49e117f5..18e1ba61 100644 --- a/test/oft/v2/NativeOFTWithFee.test.js +++ b/test/oft/v2/NativeOFTWithFee.test.js @@ -97,6 +97,8 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalAmount) expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(leftOverAmount) expect(await remoteOFTWithFee.balanceOf(owner.address)).to.be.equal(totalAmount) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(totalAmount) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(totalAmount) let ownerBalance2 = await ethers.provider.getBalance(owner.address) @@ -119,6 +121,8 @@ describe("NativeOFTWithFee: ", function () { expect(await ethers.provider.getBalance(owner.address)).to.be.equal(ownerBalance2.sub(nativeFee).sub(transFee)) expect(await nativeOFTWithFee.balanceOf(owner.address)).to.equal(leftOverAmount) expect(await remoteOFTWithFee.balanceOf(owner.address)).to.equal(0) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(leftOverAmount) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(leftOverAmount) }) it("sendFrom() w/ fee change - tokens from main to other chain", async function () { @@ -160,6 +164,8 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(alice.address)).to.be.equal(leftOverAmount) expect(await nativeOFTWithFee.balanceOf(bob.address)).to.be.equal(fee) expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalAmount.sub(fee)) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(totalAmount.sub(fee)) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(totalAmount.sub(fee)) }) it("sendFrom() w/ fee change - tokens from main to other chain without taking dust", async function () { @@ -207,6 +213,8 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(bob.address)).to.be.equal(fee) expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalMintAmount) expect(await remoteOFTWithFee.balanceOf(alice.address)).to.be.equal(totalMintAmount) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(totalMintAmount) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(totalMintAmount) }) it("sendFrom() w/ fee change - deposit before send", async function () { @@ -251,6 +259,8 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(0) expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(depositAmount) expect(await remoteOFTWithFee.balanceOf(owner.address)).to.be.equal(0) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(leftOverAmount) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(leftOverAmount) const aliceAddressBytes32 = ethers.utils.defaultAbiCoder.encode(["address"], [alice.address]) // estimate nativeFees @@ -272,6 +282,8 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(alice.address)).to.be.equal(leftOverAmount) expect(await nativeOFTWithFee.balanceOf(bob.address)).to.be.equal(fee) expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalAmount.sub(fee)) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(totalAmount.div(2)) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(totalAmount.div(2)) }) it("quote oft fee", async function () { @@ -334,6 +346,8 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalAmountMinusDust) expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(leftOverAmount) expect(await remoteOFTWithFee.balanceOf(owner.address)).to.be.equal(totalAmountMinusDust) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(totalAmountMinusDust) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(totalAmountMinusDust) }) it("sendFrom() - from != sender with addition msg.value", async function () { @@ -373,6 +387,8 @@ describe("NativeOFTWithFee: ", function () { expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(totalAmount) expect(await nativeOFTWithFee.balanceOf(owner.address)).to.be.equal(leftOverAmount) expect(await remoteOFTWithFee.balanceOf(owner.address)).to.be.equal(totalAmount) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(totalAmount) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(totalAmount) }) it("sendFrom() - from != sender with not enough native", async function () { @@ -483,6 +499,8 @@ describe("NativeOFTWithFee: ", function () { // verify tokens burned on source chain and minted on destination chain expect(await nativeOFTWithFee.balanceOf(nativeOFTWithFee.address)).to.be.equal(amount) expect(await remoteOFTWithFee.balanceOf(owner.address)).to.be.equal(amount) + expect(await nativeOFTWithFee.outboundAmount()).to.be.equal(amount) + expect(await remoteOFTWithFee.totalSupply()).to.be.equal(amount) }) it("setMinDstGas() - when type is not set on destination chain", async function () { From 3a5bd3d5f4af7c910798efb4c158c45d1fc406b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 18:14:15 -0800 Subject: [PATCH 10/12] updating require --- contracts/token/oft/v2/fee/NativeOFTWithFee.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol index 88e37ebc..a0970075 100644 --- a/contracts/token/oft/v2/fee/NativeOFTWithFee.sol +++ b/contracts/token/oft/v2/fee/NativeOFTWithFee.sol @@ -31,12 +31,12 @@ contract NativeOFTWithFee is OFTWithFee, ReentrancyGuard { ************************************************************************/ function sendFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, LzCallParams calldata _callParams) public payable virtual override { _amount = _send(_from, _dstChainId, _toAddress, _amount, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams); - require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); + require(_amount >= _minAmount, "NativeOFTWithFee: amount is less than minAmount"); } function sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, uint _minAmount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams) public payable virtual override { _amount = _sendAndCall(_from, _dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams); - require(_amount >= _minAmount, "BaseOFTWithFee: amount is less than minAmount"); + require(_amount >= _minAmount, "NativeOFTWithFee: amount is less than minAmount"); } function _send(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual override returns (uint amount) { From cf4348dcce5fb88b41ad0c3e02b0ec381ac304ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 18:21:23 -0800 Subject: [PATCH 11/12] unit test comment update --- test/oft/v2/NativeOFTWithFee.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/oft/v2/NativeOFTWithFee.test.js b/test/oft/v2/NativeOFTWithFee.test.js index 18e1ba61..9396e340 100644 --- a/test/oft/v2/NativeOFTWithFee.test.js +++ b/test/oft/v2/NativeOFTWithFee.test.js @@ -128,7 +128,7 @@ describe("NativeOFTWithFee: ", function () { it("sendFrom() w/ fee change - tokens from main to other chain", async function () { expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(ethers.utils.parseEther("0")) - // set default fee to 50% + // set default fee to 0.01% await nativeOFTWithFee.setDefaultFeeBp(1) await nativeOFTWithFee.setFeeOwner(bob.address) From e0db24f3a021214275c9a7f3cf1bd26ce37f8a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lz=2Esir=CE=94rthurmoney=28=29?= Date: Tue, 7 Nov 2023 18:38:12 -0800 Subject: [PATCH 12/12] unit test fix --- test/oft/v2/NativeOFTWithFee.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/oft/v2/NativeOFTWithFee.test.js b/test/oft/v2/NativeOFTWithFee.test.js index 9396e340..58b45cce 100644 --- a/test/oft/v2/NativeOFTWithFee.test.js +++ b/test/oft/v2/NativeOFTWithFee.test.js @@ -194,7 +194,6 @@ describe("NativeOFTWithFee: ", function () { let nativeFee = (await nativeOFTWithFee.estimateSendFee(remoteChainId, aliceAddressBytes32, totalAmount, false, defaultAdapterParams)) .nativeFee - let ld2sdRate = 10 ** (18 - sharedDecimals) let dust = totalAmount.sub(fee).mod(ld2sdRate) let totalMintAmount = (totalAmount.sub(fee)).sub(dust) @@ -252,7 +251,7 @@ describe("NativeOFTWithFee: ", function () { [owner.address, ethers.constants.AddressZero, defaultAdapterParams], { value: nativeFee.add(totalAmount.sub(depositAmount)) } // pass a msg.value to pay the LayerZero message fee ) - ).to.be.revertedWith("BaseOFTWithFee: amount is less than minAmount") + ).to.be.revertedWith("NativeOFTWithFee: amount is less than minAmount") expect(await ethers.provider.getBalance(nativeOFTWithFee.address)).to.be.equal(depositAmount) expect(await ethers.provider.getBalance(localEndpoint.address)).to.be.equal(0)