Skip to content

Commit

Permalink
Add back Foundry testHelper.sol into oft example before updating it t…
Browse files Browse the repository at this point in the history
…o handle Oz4/5 backwards compatability
  • Loading branch information
TRileySchwarz committed Feb 16, 2024
1 parent f0392c5 commit 9c3f395
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 10 deletions.
7 changes: 5 additions & 2 deletions examples/oft/contracts/MyOFT.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
//import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol";

contract MyOFT is OFT {
Expand All @@ -10,5 +10,8 @@ contract MyOFT is OFT {
string memory _symbol,
address _lzEndpoint,
address _delegate
) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}
)
// ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}
OFT(_name, _symbol, _lzEndpoint, _delegate)
{}
}
3 changes: 2 additions & 1 deletion examples/oft/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"@layerzerolabs/toolbox-hardhat": "~0.1.6",
"@nomicfoundation/hardhat-ethers": "^3.0.5",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@openzeppelin/contracts": "^5.0.1",
"@openzeppelin/contracts": "^4.8.1",
"@openzeppelin/contracts-upgradeable": "^4.8.1",
"@rushstack/eslint-patch": "^1.7.0",
"@types/chai": "^4.3.11",
"@types/mocha": "^10.0.6",
Expand Down
160 changes: 160 additions & 0 deletions examples/oft/test/foundry/MyOFT.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

// Mock imports
import { OFTMock } from "../mocks/OFTMock.sol";
import { ERC20Mock } from "../mocks/ERC20Mock.sol";
import { OFTComposerMock } from "../mocks/OFTComposerMock.sol";

// OApp imports
import { IOAppOptionsType3, EnforcedOptionParam } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OAppOptionsType3.sol";
import { OptionsBuilder } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/libs/OptionsBuilder.sol";

// OFT imports
import { IOFT, SendParam, OFTReceipt } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/interfaces/IOFT.sol";
import { MessagingFee, MessagingReceipt } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFTCore.sol";
import { OFTMsgCodec } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/libs/OFTMsgCodec.sol";
import { OFTComposeMsgCodec } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/libs/OFTComposeMsgCodec.sol";

// OZ imports
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

// Forge imports
import "forge-std/console.sol";

// DevTools imports
import { TestHelper } from "@layerzerolabs/test-devtools-evm-foundry/contracts/TestHelper.sol";

contract MyOFTTest is TestHelper {
using OptionsBuilder for bytes;

uint32 aEid = 1;
uint32 bEid = 2;

OFTMock aOFT;
OFTMock bOFT;

address public userA = address(0x1);
address public userB = address(0x2);
uint256 public initialBalance = 100 ether;

function setUp() public virtual override {
vm.deal(userA, 1000 ether);
vm.deal(userB, 1000 ether);

super.setUp();
setUpEndpoints(2, LibraryType.UltraLightNode);

aOFT = OFTMock(
_deployOApp(type(OFTMock).creationCode, abi.encode("aOFT", "aOFT", address(endpoints[aEid]), address(this)))
);

bOFT = OFTMock(
_deployOApp(type(OFTMock).creationCode, abi.encode("bOFT", "bOFT", address(endpoints[bEid]), address(this)))
);

// config and wire the ofts
address[] memory ofts = new address[](2);
ofts[0] = address(aOFT);
ofts[1] = address(bOFT);
this.wireOApps(ofts);

// mint tokens
aOFT.mint(userA, initialBalance);
bOFT.mint(userB, initialBalance);
}

function test_constructor() public {
assertEq(aOFT.owner(), address(this));
assertEq(bOFT.owner(), address(this));

assertEq(aOFT.balanceOf(userA), initialBalance);
assertEq(bOFT.balanceOf(userB), initialBalance);

assertEq(aOFT.token(), address(aOFT));
assertEq(bOFT.token(), address(bOFT));
}

function test_send_oft() public {
uint256 tokensToSend = 1 ether;
bytes memory options = OptionsBuilder.newOptions().addExecutorLzReceiveOption(200000, 0);
SendParam memory sendParam = SendParam(
bEid,
addressToBytes32(userB),
tokensToSend,
tokensToSend,
options,
"",
""
);
MessagingFee memory fee = aOFT.quoteSend(sendParam, false);

assertEq(aOFT.balanceOf(userA), initialBalance);
assertEq(bOFT.balanceOf(userB), initialBalance);

vm.prank(userA);
aOFT.send{ value: fee.nativeFee }(sendParam, fee, payable(address(this)));
verifyPackets(bEid, addressToBytes32(address(bOFT)));

assertEq(aOFT.balanceOf(userA), initialBalance - tokensToSend);
assertEq(bOFT.balanceOf(userB), initialBalance + tokensToSend);
}

function test_send_oft_compose_msg() public {
uint256 tokensToSend = 1 ether;

OFTComposerMock composer = new OFTComposerMock();

bytes memory options = OptionsBuilder
.newOptions()
.addExecutorLzReceiveOption(200000, 0)
.addExecutorLzComposeOption(0, 500000, 0);
bytes memory composeMsg = hex"1234";
SendParam memory sendParam = SendParam(
bEid,
addressToBytes32(address(composer)),
tokensToSend,
tokensToSend,
options,
composeMsg,
""
);
MessagingFee memory fee = aOFT.quoteSend(sendParam, false);

assertEq(aOFT.balanceOf(userA), initialBalance);
assertEq(bOFT.balanceOf(address(composer)), 0);

vm.prank(userA);
(MessagingReceipt memory msgReceipt, OFTReceipt memory oftReceipt) = aOFT.send{ value: fee.nativeFee }(
sendParam,
fee,
payable(address(this))
);
verifyPackets(bEid, addressToBytes32(address(bOFT)));

// lzCompose params
uint32 dstEid_ = bEid;
address from_ = address(bOFT);
bytes memory options_ = options;
bytes32 guid_ = msgReceipt.guid;
address to_ = address(composer);
bytes memory composerMsg_ = OFTComposeMsgCodec.encode(
msgReceipt.nonce,
aEid,
oftReceipt.amountReceivedLD,
abi.encodePacked(addressToBytes32(userA), composeMsg)
);
this.lzCompose(dstEid_, from_, options_, guid_, to_, composerMsg_);

assertEq(aOFT.balanceOf(userA), initialBalance - tokensToSend);
assertEq(bOFT.balanceOf(address(composer)), tokensToSend);

assertEq(composer.from(), from_);
assertEq(composer.guid(), guid_);
assertEq(composer.message(), composerMsg_);
assertEq(composer.executor(), address(this));
assertEq(composer.extraData(), composerMsg_); // default to setting the extraData to the message as well to test
}

// TODO import the rest of oft tests?
}
12 changes: 12 additions & 0 deletions examples/oft/test/mocks/ERC20Mock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract ERC20Mock is ERC20 {
constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {}

function mint(address _to, uint256 _amount) public {
_mint(_to, _amount);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

import { MyOFT } from "../MyOFT.sol";
import { MyOFT } from "../contracts/MyOFT.sol";

// @dev WARNING: This is for testing purposes only
contract MyOFTMock is MyOFT {
Expand Down
27 changes: 27 additions & 0 deletions examples/oft/test/mocks/OFTComposerMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import { IOAppComposer } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/interfaces/IOAppComposer.sol";

contract OFTComposerMock is IOAppComposer {
// default empty values for testing a lzCompose received message
address public from;
bytes32 public guid;
bytes public message;
address public executor;
bytes public extraData;

function lzCompose(
address _from,
bytes32 _guid,
bytes calldata _message,
address _executor,
bytes calldata /*_extraData*/
) external payable {
from = _from;
guid = _guid;
message = _message;
executor = _executor;
extraData = _message;
}
}
58 changes: 58 additions & 0 deletions examples/oft/test/mocks/OFTMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol";
import { SendParam } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFTCore.sol";

contract OFTMock is OFT {
constructor(
string memory _name,
string memory _symbol,
address _lzEndpoint,
address _delegate
) OFT(_name, _symbol, _lzEndpoint, _delegate) {}

function mint(address _to, uint256 _amount) public {
_mint(_to, _amount);
}

// @dev expose internal functions for testing purposes
function debit(
uint256 _amountToSendLD,
uint256 _minAmountToCreditLD,
uint32 _dstEid
) public returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
return _debit(_amountToSendLD, _minAmountToCreditLD, _dstEid);
}

function debitView(
uint256 _amountToSendLD,
uint256 _minAmountToCreditLD,
uint32 _dstEid
) public view returns (uint256 amountDebitedLD, uint256 amountToCreditLD) {
return _debitView(_amountToSendLD, _minAmountToCreditLD, _dstEid);
}

function removeDust(uint256 _amountLD) public view returns (uint256 amountLD) {
return _removeDust(_amountLD);
}

function toLD(uint64 _amountSD) public view returns (uint256 amountLD) {
return _toLD(_amountSD);
}

function toSD(uint256 _amountLD) public view returns (uint64 amountSD) {
return _toSD(_amountLD);
}

function credit(address _to, uint256 _amountToCreditLD, uint32 _srcEid) public returns (uint256 amountReceivedLD) {
return _credit(_to, _amountToCreditLD, _srcEid);
}

function buildMsgAndOptions(
SendParam calldata _sendParam,
uint256 _amountToCreditLD
) public view returns (bytes memory message, bytes memory options) {
return _buildMsgAndOptions(_sendParam, _amountToCreditLD);
}
}
15 changes: 9 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9c3f395

Please sign in to comment.