Skip to content

Commit

Permalink
refactor: make badge receiver v2 upgradable
Browse files Browse the repository at this point in the history
  • Loading branch information
noyyyy committed Jan 9, 2024
1 parent b72dc8f commit c1a4e9a
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 111 deletions.
84 changes: 20 additions & 64 deletions packages/dev/src/bridge/GalxeBadgeReceiverV2.sol
Original file line number Diff line number Diff line change
@@ -1,41 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {Ownable} from "solady/auth/Ownable.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol";
import {IERC721ReceiverUpgradeable} from
"@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol";
import {IStarNFT} from "src/bridge/interfaces/IStarNFT.sol";
import {IBadgeReceiverV2} from "src/bridge/interfaces/IBadgeReceiverV2.sol";
import {Constant} from "src/libraries/Constant.sol";
import {GalxeBadgeReceiverV2Storage} from "src/bridge/GalxeBadgeReceiverV2Storage.sol";

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

mapping(address => bool) public signers;
mapping(uint256 => bool) public allowedDst;
mapping(address => bool) public whitelistNFT;
mapping(uint256 => uint256) public usdRefund;
mapping(uint256 => uint256) public plRefund;

address public immutable usdToken;

constructor(address owner_, address usdToken_) {
_setOwner(owner_);
usdToken = usdToken_;
contract GalxeBadgeReceiverV2 is
GalxeBadgeReceiverV2Storage,
UUPSUpgradeable,
Ownable2StepUpgradeable,
IBadgeReceiverV2,
IERC721ReceiverUpgradeable
{
constructor() {
_disableInitializers();
}

function burnNFT(address nftAddr, uint256 tokenId) external {
_burnNFT(nftAddr, tokenId);
function initialize(address owner_) public initializer {
_transferOwnership(owner_);
}

function burnBatchNFT(address nftAddr, uint256[] calldata tokenIds) external {
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
_burnNFT(nftAddr, tokenId);
}
}
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}

function sendNFT(address nftAddr, uint256 dstChainId, uint256 tokenId, address receiver) external {
_sendNFT(nftAddr, dstChainId, tokenId, receiver);
Expand All @@ -51,7 +42,7 @@ contract GalxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
}

function releaseNFT(address nftAddr, address user, uint256 tokenId) external onlySigner {
IERC721(nftAddr).transferFrom(address(this), user, tokenId);
IERC721Upgradeable(nftAddr).transferFrom(address(this), user, tokenId);
emit ReleaseNFT(user, tokenId);
}

Expand All @@ -73,26 +64,6 @@ contract GalxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
emit DstValidSet(dstChainId, valid);
}

function updateUsdRefund(uint256[] calldata cids, uint256[] calldata usdAmounts) external onlyOwner {
for (uint256 i = 0; i < cids.length; i++) {
uint256 cid = cids[i];
uint256 usdAmount = usdAmounts[i];
usdRefund[cid] = usdAmount;
}

emit UsdRefundSet(cids, usdAmounts);
}

function updatePlUsdRefund(uint256[] calldata cids, uint256[] calldata pls) external onlyOwner {
for (uint256 i = 0; i < cids.length; i++) {
uint256 cid = cids[i];
uint256 pl = pls[i];
plRefund[cid] = pl;
}

emit PlRefundSet(cids, pls);
}

function onERC721Received(address, address, uint256, bytes calldata) public pure override returns (bytes4) {
return this.onERC721Received.selector;
}
Expand All @@ -105,28 +76,13 @@ contract GalxeBadgeReceiverV2 is IBadgeReceiverV2, Ownable, IERC721Receiver {
revert DstChainIdIsNotAllowed();
}

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

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

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

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

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

// get refund USD
uint256 refundAmount = usdRefund[cid];

// refund
IERC20(usdToken).safeTransfer(msg.sender, refundAmount);

emit BurnAndRefund(nftAddr, cid, tokenId, refundAmount, plRefund[cid]);
}

function _checkSigner() internal view {
if (!signers[msg.sender]) {
revert NotSigner();
Expand Down
10 changes: 10 additions & 0 deletions packages/dev/src/bridge/GalxeBadgeReceiverV2Storage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

contract GalxeBadgeReceiverV2Storage {
mapping(address => bool) public signers;
mapping(uint256 => bool) public allowedDst;
mapping(address => bool) public whitelistNFT;

uint256[47] private __gap;
}
80 changes: 40 additions & 40 deletions packages/dev/test/uint/concrete/GBR_V2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -96,59 +96,59 @@ contract GBR_V2_Test is GalxeBadgeReceiverV2Test, IBadgeReceiverV2Def {
assertEq(starNFT.ownerOf(4), address(galxeBadgeReceiverV2));
}

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

vm.expectRevert(IBadgeReceiverV2Def.InvalidNFTAddr.selector);
galxeBadgeReceiverV2.burnNFT(address(starNFT), 1);
}
// 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);
// function test_BurnNFT_Successfully() public {
// changePrank(users.admin);
// galxeBadgeReceiverV2.updateValidNftAddr(address(starNFT), true);
// galxeBadgeReceiverV2.updateDstValidity(1, true);

changePrank(users.alice);
// changePrank(users.alice);

assertEq(starNFT.ownerOf(1), 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);
// // 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);
// galxeBadgeReceiverV2.burnNFT(address(starNFT), 1);

// check owner change
assertEq(starNFT.ownerOf(1), Constant.BLACK_HOLE_ADDRESS);
}
// // check owner change
// assertEq(starNFT.ownerOf(1), Constant.BLACK_HOLE_ADDRESS);
// }

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

changePrank(users.alice);
// changePrank(users.alice);

assertEq(starNFT.ownerOf(2), users.alice);
assertEq(starNFT.ownerOf(3), users.alice);
assertEq(starNFT.ownerOf(4), users.alice);
// assertEq(starNFT.ownerOf(2), users.alice);
// assertEq(starNFT.ownerOf(3), users.alice);
// assertEq(starNFT.ownerOf(4), users.alice);

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

uint256[] memory tokenIds = new uint256[](3);
tokenIds[0] = 2;
tokenIds[1] = 3;
tokenIds[2] = 4;
// uint256[] memory tokenIds = new uint256[](3);
// tokenIds[0] = 2;
// tokenIds[1] = 3;
// tokenIds[2] = 4;

galxeBadgeReceiverV2.burnBatchNFT(address(starNFT), tokenIds);
// galxeBadgeReceiverV2.burnBatchNFT(address(starNFT), tokenIds);

// check owner change
assertEq(starNFT.ownerOf(2), Constant.BLACK_HOLE_ADDRESS);
assertEq(starNFT.ownerOf(2), Constant.BLACK_HOLE_ADDRESS);
assertEq(starNFT.ownerOf(2), Constant.BLACK_HOLE_ADDRESS);
// // check owner change
// assertEq(starNFT.ownerOf(2), Constant.BLACK_HOLE_ADDRESS);
// assertEq(starNFT.ownerOf(2), Constant.BLACK_HOLE_ADDRESS);
// assertEq(starNFT.ownerOf(2), Constant.BLACK_HOLE_ADDRESS);

// TODO: check usd balance;
}
// // TODO: check usd balance;
// }
}
12 changes: 6 additions & 6 deletions packages/dev/test/uint/fuzz/GBROnlyOwnerTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ contract GBR_OnlyOwner_Test is GalxeBadgeReceiverV2Test {
galxeBadgeReceiverV2.updateDstValidity(1, true);
}

function testFuzz_onlyOwner_UpdateUsdRefund(address eve) public onlyOwnerCanCall(eve) {
galxeBadgeReceiverV2.updateUsdRefund(new uint256[](1), new uint256[](1));
}
// function testFuzz_onlyOwner_UpdateUsdRefund(address eve) public onlyOwnerCanCall(eve) {
// galxeBadgeReceiverV2.updateUsdRefund(new uint256[](1), new uint256[](1));
// }

function testFuzz_onlyOwner_UpdatePlRefund(address eve) public onlyOwnerCanCall(eve) {
galxeBadgeReceiverV2.updatePlUsdRefund(new uint256[](1), new uint256[](1));
}
// function testFuzz_onlyOwner_UpdatePlRefund(address eve) public onlyOwnerCanCall(eve) {
// galxeBadgeReceiverV2.updatePlUsdRefund(new uint256[](1), new uint256[](1));
// }
}
3 changes: 2 additions & 1 deletion packages/dev/test/uint/shared/GalxeBadgeReceiverV2.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ abstract contract GalxeBadgeReceiverV2Test is BaseTest {
}

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

function approveNFT() internal {
Expand Down

0 comments on commit c1a4e9a

Please sign in to comment.