Skip to content

Commit

Permalink
test: add some unit
Browse files Browse the repository at this point in the history
  • Loading branch information
noyyyy committed Dec 1, 2023
1 parent b47e1a6 commit bbec58d
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 10 deletions.
16 changes: 8 additions & 8 deletions packages/dev/src/bridge/GalxeBadgeReceiverV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import {IStarNFT} from "src/bridge/interfaces/IStarNFT.sol";
import {IBadgeReceiverV2} from "src/bridge/interfaces/IBadgeReceiverV2.sol";
import {Constant} from "src/libraries/Constant.sol";

contract GalxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
using SafeERC20 for IERC20;

address constant BLACK_HOLE_ADDRESS = address(1);

mapping(address => bool) public signers;
mapping(uint256 => bool) public allowedDst;
mapping(address => bool) public whitelistNFT;
Expand All @@ -38,8 +37,8 @@ contract GalxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
}
}

function sendNFT(address nftAddr, uint256 dstChainId, uint256 tokenId, address from, address receiver) external {
_sendNFT(nftAddr, dstChainId, tokenId, from, receiver);
function sendNFT(address nftAddr, uint256 dstChainId, uint256 tokenId, address receiver) external {
_sendNFT(nftAddr, dstChainId, tokenId, receiver);
}

function sendBatchNFT(address nftAddr, uint256[] calldata tokenIds) external {
Expand Down Expand Up @@ -76,23 +75,24 @@ contract GalxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
return this.onERC721Received.selector;
}

function _sendNFT(address nftAddr, uint256 dstChainId, uint256 tokenId, address from, address receiver)
function _sendNFT(address nftAddr, uint256 dstChainId, uint256 tokenId, address receiver)
internal
onlyValidNftAddr(nftAddr)
{
if (!allowedDst[dstChainId]) {
revert DstChainIdIsNotAllowed();
}
IERC721(nftAddr).transferFrom(from, address(this), tokenId);

IERC721(nftAddr).transferFrom(msg.sender, address(this), tokenId);

uint256 cid = IStarNFT(nftAddr).cid(tokenId);

emit SendNFT(dstChainId, tokenId, cid, nftAddr, from, receiver);
emit SendNFT(dstChainId, tokenId, cid, nftAddr, msg.sender, receiver);
}

function _burnNFT(address nftAddr, uint256 tokenId) internal onlyValidNftAddr(nftAddr) {
// burn
IERC721(nftAddr).transferFrom(msg.sender, BLACK_HOLE_ADDRESS, tokenId);
IERC721(nftAddr).transferFrom(msg.sender, Constant.BLACK_HOLE_ADDRESS, tokenId);

uint256 cid = IStarNFT(nftAddr).cid(tokenId);

Expand Down
6 changes: 6 additions & 0 deletions packages/dev/src/libraries/Constant.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.19;

library Constant {
address constant BLACK_HOLE_ADDRESS = address(1);
}
2 changes: 1 addition & 1 deletion packages/dev/test/ArcanaV2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ contract ArcanaV2Test is Test, IP12ArcanaDef {
deal(address(_mockErc20), address(_arcanaV2), 100 ether);
assertEq(_mockErc20.balanceOf(address(_arcanaV2)), 100 ether);

vm.expectEmit();
vm.expectEmit(true, true, true, true);
emit Withdrawn(address(_mockErc20), _owner, 100 ether);

vm.prank(_owner);
Expand Down
14 changes: 14 additions & 0 deletions packages/dev/test/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity >=0.8.19 <0.9.0;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20MissingReturn} from "test/mocks/ERC20/ERC20MissingReturn.sol";
import {Test} from "forge-std/Test.sol";
import {StarNFT} from "test/mocks/StarNFT.sol";

struct Users {
// Default admin
Expand All @@ -18,10 +19,14 @@ struct Users {
abstract contract BaseTest is Test {
Users internal users;
ERC20MissingReturn internal usdt;
StarNFT internal starNFT;

function setUp() public virtual {
users = Users({admin: createUser("admin"), alice: createUser("alice"), signer: createUser("signer")});
usdt = new ERC20MissingReturn("Tether USD", "USDT", 6);
starNFT = new StarNFT();

mintStartNFT();
}

/// @dev Generates a user, labels its address, and funds it with test assets.
Expand All @@ -30,4 +35,13 @@ abstract contract BaseTest is Test {
vm.deal({account: user, newBalance: 100 ether});
return user;
}

function mintStartNFT() internal {
starNFT.mint(users.alice, 1, 1);
starNFT.mint(users.alice, 2, 2);
starNFT.mint(users.alice, 3, 2);
starNFT.mint(users.alice, 4, 3);
starNFT.mint(users.alice, 5, 3);
starNFT.mint(users.alice, 6, 3);
}
}
30 changes: 30 additions & 0 deletions packages/dev/test/mocks/StarNFT.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.19;

import {ERC721} from "solady/tokens/ERC721.sol";
import {IStarNFT} from "src/bridge/interfaces/IStarNFT.sol";

contract StarNFT is ERC721, IStarNFT {
mapping(uint256 => uint256) internal _cid;

function mint(address user, uint256 tokenId, uint256 cid_) public {
_mint(user, tokenId);
_cid[tokenId] = cid_;
}

function cid(uint256 tokenId) public view override returns (uint256) {
return _cid[tokenId];
}

function name() public pure override returns (string memory) {
return "Star NFT";
}

function symbol() public pure override returns (string memory) {
return "SNFT";
}

function tokenURI(uint256) public pure override returns (string memory) {
return "";
}
}
94 changes: 94 additions & 0 deletions packages/dev/test/uint/concrete/GBRV2.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import {GalxeBadgeReceiverV2Test} from "test/uint/shared/GalxeBadgeReceiverV2.t.sol";
import {IBadgeReceiverV2Def} from "src/bridge/interfaces/IBadgeReceiverV2.sol";
import {Constant} from "src/libraries/Constant.sol";

contract GBRV2_Test is GalxeBadgeReceiverV2Test, IBadgeReceiverV2Def {
function testUpdateValidNftAddr(address nftAddr, bool valid) public {
changePrank(users.admin);
assertEq(galxeBadgeReceiverV2.whitelistNFT(nftAddr), false);
emit ValidNftAddrSet(nftAddr, valid);
galxeBadgeReceiverV2.updateValidNftAddr(nftAddr, valid);
assertEq(galxeBadgeReceiverV2.whitelistNFT(nftAddr), valid);
}

function testUpdateSigner(address signer, bool valid) public {
changePrank(users.admin);
assertEq(galxeBadgeReceiverV2.signers(signer), false);
emit SignerSet(signer, valid);
galxeBadgeReceiverV2.updateSigner(signer, valid);
assertEq(galxeBadgeReceiverV2.signers(signer), valid);
}

function testUpdateDstValidity(uint256 chainId, bool valid) public {
changePrank(users.admin);
assertEq(galxeBadgeReceiverV2.allowedDst(chainId), false);
emit DstValidSet(chainId, valid);
galxeBadgeReceiverV2.updateDstValidity(chainId, valid);
assertEq(galxeBadgeReceiverV2.allowedDst(chainId), valid);
}

function test_SendNFT_Revert_InvalidNFTAddr() public {
changePrank(users.alice);

vm.expectRevert(IBadgeReceiverV2Def.InvalidNFTAddr.selector);
galxeBadgeReceiverV2.sendNFT(address(starNFT), 1, 1, users.alice);
}

function test_SendNFT_Revert_DstChainIdIsNotAllowed() public {
changePrank(users.admin);
galxeBadgeReceiverV2.updateValidNftAddr(address(starNFT), true);

changePrank(users.alice);

vm.expectRevert(IBadgeReceiverV2Def.DstChainIdIsNotAllowed.selector);
galxeBadgeReceiverV2.sendNFT(address(starNFT), 1, 1, users.alice);
}

function test_SendNFT_Successfully() public {
changePrank(users.admin);
galxeBadgeReceiverV2.updateValidNftAddr(address(starNFT), true);
galxeBadgeReceiverV2.updateDstValidity(1, true);

changePrank(users.alice);

assertEq(starNFT.ownerOf(1), users.alice);

// check event emit
vm.expectEmit(true, true, true, true);
emit SendNFT(1, 1, 1, address(starNFT), users.alice, users.alice);

galxeBadgeReceiverV2.sendNFT(address(starNFT), 1, 1, users.alice);

// check owner change
assertEq(starNFT.ownerOf(1), address(galxeBadgeReceiverV2));
}

function test_BurnNFT_Revert_InvalidNFTAddr() public {
changePrank(users.alice);

vm.expectRevert(IBadgeReceiverV2Def.InvalidNFTAddr.selector);
galxeBadgeReceiverV2.burnNFT(address(starNFT), 1);
}

function test_BurnNFT_Successfully() public {
changePrank(users.admin);
galxeBadgeReceiverV2.updateValidNftAddr(address(starNFT), true);
galxeBadgeReceiverV2.updateDstValidity(1, true);

changePrank(users.alice);

assertEq(starNFT.ownerOf(1), users.alice);

// check event emit
// vm.expectEmit(true, true, true, true);
// emit BurnAndRefund(1, 1, 1, address(starNFT), users.alice, users.alice);

galxeBadgeReceiverV2.burnNFT(address(starNFT), 1);

// check owner change
assertEq(starNFT.ownerOf(1), Constant.BLACK_HOLE_ADDRESS);
}
}
8 changes: 7 additions & 1 deletion packages/dev/test/uint/shared/GalxeBadgeReceiverV2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,21 @@ import {BaseTest} from "test/Base.t.sol";
import {GalxeBadgeReceiverV2} from "src/bridge/GalxeBadgeReceiverV2.sol";
import {Ownable} from "solady/auth/Ownable.sol";

contract GalxeBadgeReceiverV2Test is BaseTest {
abstract contract GalxeBadgeReceiverV2Test is BaseTest {
GalxeBadgeReceiverV2 internal galxeBadgeReceiverV2;

function setUp() public override {
super.setUp();
deploy();
approveNFT();
}

function deploy() internal {
galxeBadgeReceiverV2 = new GalxeBadgeReceiverV2(users.admin, address(usdt));
}

function approveNFT() internal {
changePrank(users.alice);
starNFT.setApprovalForAll(address(galxeBadgeReceiverV2), true);
}
}

0 comments on commit bbec58d

Please sign in to comment.